Gatsby ブログを GitHub Actions から Cloudflare Pages へデプロイしたところ、build までは成功したのに、最後の公開ステップだけが次のエラーで失敗した。
No ref found for: content/home-assistant-energy-statistics直接の原因は、cloudflare/pages-action@1 が GitHub Deployment を作るとき、マージ後に削除した Pull Request の head branch を ref として使ったことだった。workflow で checkout していたのは main だったが、build 元の ref と deployment に渡す ref は別だった。
最終的には非推奨の pages-action から wrangler-action へ移行し、checkout と Cloudflare Pages の deployment branch を main に固定した。変更後の workflow で deployment が成功し、本番 URL の表示にも問題がないことまで確認できた。
main の build 成功後に No ref found で公開だけ失敗した
workflow は、deploy ラベルを付けた Pull Request が main へマージされたときに実行する構成だった。
失敗した実行でも、次の処理は完了していた。
- 依存関係のインストール
- Prettier による整形
- OGP キャッシュの取得
- 8 suites、59 tests の実行
- Gatsby の build
エラーが出たのは、その後の Publish to Cloudflare Pages ステップだった。依存関係や Gatsby build を疑うより、公開処理が参照した ref を切り分ける必要があった。
実行環境とマージ後に動く workflow
問題が起きた時点の主な環境は次のとおりだった。
- runner: Ubuntu 24.04.4(
ubuntu-24.04) - Node.js: 18.20.8
- Gatsby: 5
- 公開 Action:
cloudflare/pages-action@1 - トリガー:
pull_requestのclosed - build 成果物:
./public
変更前の公開部分は次のようになっていた。
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: setup node
uses: actions/setup-node@v4
with:
node-version: "18.x"
- name: Publish to Cloudflare Pages
uses: cloudflare/pages-action@1
with:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
projectName: sakakinox-gatsby-blog
directory: ./public
gitHubToken: ${{ secrets.GITHUB_TOKEN }}認証情報は GitHub Actions の Secrets から渡している。値そのものはこの記事には記載しない。
build 元は main なのに pages-action は削除済み branch を参照した
失敗までの時系列を確認すると、状況がつながった。
- 2026-08-08 16:31:46 JST に Pull Request #60 を
mainへマージした。 - マージ後、head branch の
content/home-assistant-energy-statisticsを削除した。 - 約 15 秒後の 16:32:00 JST に workflow の job が始まった。
- checkout と Gatsby build は
mainで成功した。 pages-actionは GitHub Deployment の作成時に Pull Request の head branch 名を ref として使った。- その ref はすでに削除済みだったため、GitHub API が HTTP 422 の
No ref foundを返した。
前日の 2026-08-07 に成功した実行では、対象 Pull Request の head branch がリモートに残っていた。成功時と失敗時の差も、deployment 作成時に branch が存在したかどうかで説明できた。
ここで重要だったのは、checkout と deployment が同じ ref を使うとは限らない点だった。main のコードを正常に build できても、公開 Action が別の branch を GitHub Deployment の ref に使えば、公開ステップだけ失敗する。
git branch -r の表示だけでは remote branch の実在を確認できなかった
調査中、次のコマンドでは削除したはずの branch が見えていた。
git branch -rしかし、これはローカルに残った remote-tracking ref だった。prune していなければ、GitHub 上の remote branch が削除された後も表示される。
remote branch の実在確認には、リモートへ問い合わせる必要がある。
git ls-remote origin refs/heads/content/home-assistant-energy-statisticsこの結果と GitHub 上で branch を削除した操作を照合し、git branch -r の表示だけを根拠に「リモートにも branch が存在する」と判断したのが誤りだったと分かった。
非推奨の pages-action から wrangler-action へ移行した
branch 削除が No ref found の直接原因だった。一方、調査中に cloudflare/pages-action が非推奨で、リポジトリもアーカイブされていることを確認した。これは今回のエラーの直接原因ではないが、今後も使い続けるより、Cloudflare が案内する wrangler-action へ移行する理由になった。
pages-action は projectName や directory を個別の input として受け取る Pages 用 Action だった。wrangler-action では、Wrangler CLI の command として Pages deployment を指定する。
移行時には job の権限も明示した。
jobs:
build-deploy:
permissions:
contents: read
deployments: write
steps:
- name: Publish to Cloudflare Pages
uses: cloudflare/wrangler-action@v4
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy ./public --project-name=sakakinox-gatsby-blog
gitHubToken: ${{ secrets.GITHUB_TOKEN }}contents: read はリポジトリ内容の読み取り、deployments: write は GitHub Deployment の作成・更新に使う。pages deploy ./public では、事前に Gatsby で build した public ディレクトリを、指定した Cloudflare Pages プロジェクトへ Direct Upload する。
この変更は Pull Request #71 で main へマージした。
Wrangler 4 は Node.js 18.20.8 では起動できなかった
wrangler-action@v4 へ変更すれば終わりだと思ったが、次の deployment では別の問題が起きた。
前段の install、format、test、Gatsby build は再び成功した。その後、Action が Wrangler 4.47.0 をインストールしたところ、Node.js の version check で終了した。
ログから必要な部分だけ抜き出すと、条件は次のとおりだった。
- workflow の Node.js: 18.20.8
- Wrangler が示した最低要件: Node.js 20.0.0
- インストールされた
[email protected]の要件: Node.js 20.18.1 以上 - 結果: deploy コマンドを実行する前に exit code 1
そこで Node.js を 18.x から 22.x に変更した。
- name: setup node
uses: actions/setup-node@v4
with:
node-version: "22.x"Node.js 22 は今回選択した修正バージョンであり、「Wrangler 4 は Node.js 22 以上が必須」という意味ではない。実行ログで Wrangler 自体が示した最低要件は Node.js 20.0.0、同時にインストールされた undici の要件は 20.18.1 以上だった。この追加修正は Pull Request #72 として分けてマージした。
checkout と Pages deployment の branch を main に固定した
wrangler-action への移行後、同じように Pull Request の head branch に依存しないよう、checkout と Pages deployment の branch を明示的に main へ固定した。
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
# install、test、build などは省略
- name: Publish to Cloudflare Pages
uses: cloudflare/wrangler-action@v4
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy ./public --project-name=sakakinox-gatsby-blog --branch=main
gitHubToken: ${{ secrets.GITHUB_TOKEN }}ref: main で build 対象を固定し、--branch=main で Cloudflare Pages に渡す branch も固定した。Pull Request の head branch をマージ直後に削除する運用でも、workflow が削除済み branch に依存しない状態を意図している。
この変更は Pull Request #74 として作成し、YAML 構文、Prettier、git diff --check を確認した。マージ後には変更後の workflow で Cloudflare Pages への deployment が成功し、本番 URL の表示にも問題がないことを確認した。
build の ref と deployment の branch は別々に明示する
今回の No ref found は、main の build が成功していたため、最初は branch 削除との関係が分かりにくかった。実際には、checkout の ref と GitHub Deployment に渡された ref が別で、後者だけが削除済みだった。
非推奨の pages-action から wrangler-action へ移行したことで、Pages deployment を Wrangler のコマンドとして明示できた。さらに checkout と deployment branch を main に固定し、Pull Request の head branch を削除する運用から切り離した。
今後、build 後の公開ステップだけが ref エラーになる場合は、依存関係や認証情報を先に変えるのではなく、次の二つを分けて確認する。
- 何を checkout して build したか
- 公開処理がどの branch または ref を deployment に使ったか
main 固定後の workflow で deployment と本番表示まで確認できたため、build 元と公開先 branch の両方を明示する対応まで完了した。
workflow の変更は PAT の workflow スコープ不足でも一度止まった
調査と修正の途中では、workflow ファイルを含む commit を push しようとした際、Personal Access Token に workflow スコープがなく拒否された。当時の記録から再構成したエラー内容は次のとおりである。
! [remote rejected] xxx -> xxx (refusing to allow a Personal Access Token to create or update workflow `.github/workflows/master.yaml` without `workflow` scope)
error: failed to push some refs to `xxx`Token の値や認証情報を変更内容へ含めず、必要なスコープを追加した後に push できた。これは No ref found とは別問題だが、実際の修正順序に影響した失敗として残しておく。
参考
おしまい


