この記事は、Cloudflare上でAIプロダクトを運用する中で見つけた落とし穴シリーズの1本である。自社が運営する求人比較サイトで、公開ページのサーバー側描画をWorkerに実装してデプロイしたのに、一部のページだけ反映されていなかった。原因は静的アセットの仕組みそのものと、検証タイミングの2つが重なっていた、という話をまとめる。
この記事で分かること
- [assets]バインディングを使うWorkerで、一部のパスだけ反映されない理由
- デプロイ直後の検証で「効いていない」ように見えるもう1つの原因
- 両方を切り分ける見分け方
この記事で分からないこと(正直に書く)
- 本記事の対象以外のWorkerで同じ設定の抜けが残っていないかは、本記事の材料だけでは分からない
何が起きたか
公開ページのサーバー側描画をWorkerに実装してデプロイしたところ、トップページと一覧ページはJS実行前のテキストが変わらず、動作確認用に付けていたレスポンスヘッダーも付いていなかった。一方でsitemap.xmlとrobots.txtは実装どおりに動いていた(出所: 自社の運用記録、確認日2026-09-06)。「一部のパスだけ動く」という見え方だった。
なぜ気づけなかったか
最初に疑ったのはデプロイ直後の反映待ちだった。別の案件で、デプロイ直後の数秒から数十秒はバージョンの伝播中で古いコードに当たることがあり、1回目と2回目のリクエストで結果が違う、という事例を経験していたためである(出所: 自社の運用記録、確認日2026-09-06)。数秒待って再検証したが結果は変わらず、この可能性は外れた。実際の原因は別で、[assets]バインディングを使うWorkerは、静的ファイルに一致するリクエストをアセット側が直接返し、Workerを起動しない仕様になっていた。トップページと一覧ページには対応する静的ファイルが存在したためWorkerに届かず、対応する静的ファイルが無いsitemap.xmlだけがWorkerに届いていた。Cloudflareの公式ドキュメントでも、既定ではリクエストされたURLが静的アセットのディレクトリ内のファイルに一致する場合、そのファイルはWorkerのコードを呼び出すことなく配信される、と説明されている(https://developers.cloudflare.com/workers/static-assets/, 確認日2026-09-06)。
どう直したか
設定ファイルのassets項目に、Workerを先に実行したいパスだけを列挙するrun_worker_firstを追加した。この値を全パス対象にすると、静的ファイルへのアクセスまで毎回Workerを経由することになり無駄が大きいため、対象は先に実行したいパスだけに絞った。あわせて、デプロイ直後の検証は1回で判断せず、数秒待って2回目を打ち、1回目と2回目で結果が違えば伝播待ちだと判断する、という手順を検証の手順に加えた。
同じ構成の製品で先に見る場所
自社はconvaiなど複数のプロダクトで[assets]バインディングを使うWorkerを運用している。同じ構成のプロダクトでは、公開ページに対応する静的HTMLファイルが存在するかをまず確認する。存在する場合、Worker側の実装を直しても、run_worker_firstにそのパスを追加しない限り反映されない。あわせて、デプロイ直後の検証は2回打ち、結果が変わるかどうかで伝播待ちかどうかを見分けるとよい。
静的アセットの層とWorkerの層のどちらが応答しているかを取り違えると、Workerが自前で持つキャッシュの記事やDurable ObjectsのSQLite無料枠の記事と同様、原因の切り分けに時間がかかる。関連してRAGの保管費用の記事も参照してほしい。
自社のCloudflare Workers構成・デプロイ検証について相談したい場合は、お問い合わせから編集部まで連絡してほしい。
よくある質問
Q1. 静的アセットを使うWorkerで一部のパスだけ動かないのはなぜか
静的ファイルに一致するリクエストはアセット側が直接応答し、Workerを起動しない仕様になっているため。対応する静的ファイルが無いパスだけWorkerに届く。
Q2. デプロイ直後の検証で「効いていない」と誤判定しないためにはどうすればよいか
1回だけで判断せず、数秒待って2回目を打つ。1回目と2回目で結果が違えばバージョンの伝播待ちであって、実装の不具合ではない。
Q3. run_worker_firstはどう設定すればよいか
Workerを先に実行したいパスだけを配列で列挙する。対応する静的ファイルが存在するページのパスを個別に指定する。