{"record":{"id":"abaf6860a028f359","repo":"withastro/astro","slug":"astro-locals-runtime-caches-has-been-removed-in-as","errorCode":null,"errorMessage":"Astro.locals.runtime.caches has been removed in Astro v6. Use the global 'caches' object instead.","messagePattern":"Astro\\.locals\\.runtime\\.caches has been removed in Astro v6\\. Use the global 'caches' object instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/cloudflare/src/utils/cf-helpers.ts","lineNumber":82,"sourceCode":"export function createLocals(ctx: ExecutionContext): Runtime {\n\tconst locals: Runtime = {\n\t\tcfContext: ctx,\n\t};\n\tObject.defineProperty(locals, 'runtime', {\n\t\tenumerable: false,\n\t\tvalue: {\n\t\t\tget env(): never {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Astro.locals.runtime.env has been removed in Astro v6. Use 'import { env } from \"cloudflare:workers\"' instead.`,\n\t\t\t\t);\n\t\t\t},\n\t\t\tget cf(): never {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Astro.locals.runtime.cf has been removed in Astro v6. Use 'Astro.request.cf' instead.`,\n\t\t\t\t);\n\t\t\t},\n\t\t\tget caches(): never {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Astro.locals.runtime.caches has been removed in Astro v6. Use the global 'caches' object instead.`,\n\t\t\t\t);\n\t\t\t},\n\t\t\tget ctx(): never {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Astro.locals.runtime.ctx has been removed in Astro v6. Use 'Astro.locals.cfContext' instead.`,\n\t\t\t\t);\n\t\t\t},\n\t\t},\n\t});\n\treturn locals;\n}\n\n/**\n * Extracts the client IP address from the `cf-connecting-ip` header.\n */\nexport function getClientAddress(request: Request): string | undefined {\n\treturn getValidatedIpFromHeader(request.headers.get('cf-connecting-ip'));","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/integrations/cloudflare/src/utils/cf-helpers.ts#L64-L100","documentation":"Third of the Astro v6 `locals.runtime` removals: the `caches` getter now throws, directing you to the global `caches` object that workerd exposes. The Cache API was always ambient in Cloudflare Workers; the locals copy was a compatibility shim that v6 deleted.","triggerScenarios":"Code such as `Astro.locals.runtime.caches.default.match(...)` executing in an Astro v6 Cloudflare project throws immediately from the trap getter.","commonSituations":"Cached-response or edge-cache tag logic written for Astro v5 being carried into v6; shared components reused across adapter versions.","solutions":["Use the global `caches` directly: `caches.default.match(request)`.","Type it via `@cloudflare/workers-types` so TS knows the global.","Remove all `locals.runtime` reads in one sweep (env/cf/ctx are also gone).","Pin Astro v5 + adapter pair if the cache code cannot be migrated now."],"exampleFix":"// before\nconst cached = await Astro.locals.runtime.caches.default.match(req);\n\n// after\nconst cached = await caches.default.match(req);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"declare const caches: CacheStorage; // from @cloudflare/workers-types\nfunction safeCaches(locals: App.Locals): CacheStorage | undefined {\n  if (typeof caches !== 'undefined') return caches; // workerd global (preferred in v6)\n  const runtime = (locals as Record<string, unknown>).runtime;\n  if (!runtime || typeof runtime !== 'object') return undefined;\n  try {\n    return (runtime as { caches: unknown }).caches as CacheStorage;\n  } catch {\n    return undefined; // v6 trap — callers must use the global `caches`\n  }\n}","tryCatchPattern":null,"preventionTips":["Use the ambient `caches` global directly; delete all locals.runtime.caches references.","Include `@cloudflare/workers-types` in tsconfig types so the global resolves.","Wrap cache reads in existence checks so local/dev environments without caches skip gracefully."],"tags":["cloudflare","astro-v6","breaking-change","cache-api","migration"],"backgroundTag":"removed-api-migration","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}