Raised on #144 (packages/web/src/routes/internal.ts:191) and deliberately not folded into that PR: it is not a defect in #144's diff, it is a question about whether #144's diff is load-bearing.
The two candidate causes
#143 is: every OG card that was not already warm rendered the neutral placeholder, and three consecutive cold requests never self-healed. #144 attributes that to the /internal/* result cache being unusable, for two reasons — the key URL was the non-routable https://web/..., and the key parts did not match the public routes'. It fixes both.
There is a third candidate that produces exactly the same symptom:
caches.default may not be attached to a zone when the Worker is invoked through a Service Binding.
The incoming request for that invocation is https://web/internal/..., which belongs to no zone. If the cache namespace follows the invocation rather than the URL passed to match()/put(), then rewriting the key URL to https://released.blabberate.com changes nothing: every put still no-ops, /internal still never self-heals, and the :pinpartial marker, the :og flight key and the back-off bypass all sit on a permanently cold path.
Nothing currently discriminates
- The unit tests use an in-memory
cacheStore, so they pass under either cause.
- The preview env cannot tell us:
*.workers.dev is not a custom domain.
- Cloudflare's own docs are silent on it. Cache API runtime docs enumerate the cases where the Cache API has no effect — dashboard editor, Playground previews, Workers fronted by Cloudflare Access — and state that "Workers deployed to custom domains have access to functional cache operations." Service bindings are not mentioned in either direction. Checked 2026-08-27.
The fix that is correct under BOTH hypotheses
Have web-og call the binding on the public origin instead of on https://web:
// packages/web-og/src/index.tsx:37,53,71,80,91,103
const internalUrl = `${env.PUBLIC_BASE_URL}/internal/result/...`; // not `https://web/internal/...`
Then the invocation URL is routable and on the zone, so the cache works whichever way the namespace is scoped. It also removes machinery from web: cacheOrigin's ?? chain, originOf()'s single-label-host guard, and the wrangler.toml suite that exists only to stop that chain falling through to a non-routable origin (packages/web/src/routes/internal.ts:45-137, packages/web/wrangler.toml).
That is a net simplification and it is hypothesis-independent, which is why it is worth doing regardless of the answer below.
How to settle it empirically
After #144 is live, request a cold OG URL (a sha never requested before) twice:
GET https://og.released.blabberate.com/r/<owner>/<repo>/c/<fresh-sha>.png
Either way the check is worth running once, because the answer decides how much of #144 can be deleted.
Related: #147 (the remaining sha:<7> vs full-sha key-part misalignment).
Raised on #144 (
packages/web/src/routes/internal.ts:191) and deliberately not folded into that PR: it is not a defect in #144's diff, it is a question about whether #144's diff is load-bearing.The two candidate causes
#143 is: every OG card that was not already warm rendered the neutral placeholder, and three consecutive cold requests never self-healed. #144 attributes that to the
/internal/*result cache being unusable, for two reasons — the key URL was the non-routablehttps://web/..., and the key parts did not match the public routes'. It fixes both.There is a third candidate that produces exactly the same symptom:
The incoming request for that invocation is
https://web/internal/..., which belongs to no zone. If the cache namespace follows the invocation rather than the URL passed tomatch()/put(), then rewriting the key URL tohttps://released.blabberate.comchanges nothing: everyputstill no-ops,/internalstill never self-heals, and the:pinpartialmarker, the:ogflight key and the back-off bypass all sit on a permanently cold path.Nothing currently discriminates
cacheStore, so they pass under either cause.*.workers.devis not a custom domain.The fix that is correct under BOTH hypotheses
Have
web-ogcall the binding on the public origin instead of onhttps://web:Then the invocation URL is routable and on the zone, so the cache works whichever way the namespace is scoped. It also removes machinery from
web:cacheOrigin's??chain,originOf()'s single-label-host guard, and thewrangler.tomlsuite that exists only to stop that chain falling through to a non-routable origin (packages/web/src/routes/internal.ts:45-137,packages/web/wrangler.toml).That is a net simplification and it is hypothesis-independent, which is why it is worth doing regardless of the answer below.
How to settle it empirically
After #144 is live, request a cold OG URL (a sha never requested before) twice:
max-age=86400, real card) → the key URL was the cause, fix(web): align /internal/* result cache with the public routes (#143) #144's machinery is load-bearing.max-age=60) → the cache is invocation-scoped, and fix(web): align /internal/* result cache with the public routes (#143) #144 fixed a real misalignment that was not the binding constraint. Do thePUBLIC_BASE_URLchange above.Either way the check is worth running once, because the answer decides how much of #144 can be deleted.
Related: #147 (the remaining
sha:<7>vs full-sha key-part misalignment).