{"record":{"id":"378d336953a14f6b","repo":"withastro/astro","slug":"astro-locals-runtime-cf-has-been-removed-in-astro","errorCode":null,"errorMessage":"Astro.locals.runtime.cf has been removed in Astro v6. Use 'Astro.request.cf' instead.","messagePattern":"Astro\\.locals\\.runtime\\.cf has been removed in Astro v6\\. Use 'Astro\\.request\\.cf' instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/cloudflare/src/utils/cf-helpers.ts","lineNumber":77,"sourceCode":"\n/**\n * Creates the Cloudflare-specific locals object with `cfContext`\n * and deprecated `runtime` property getters.\n */\nexport 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","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/integrations/cloudflare/src/utils/cf-helpers.ts#L59-L95","documentation":"Part of the same Astro v6 removal: `Astro.locals.runtime.cf` no longer exists, and the adapter's trap getter throws this message pointing at the replacement. `cf` (request metadata like country, ASN, TLS info) must now be read from `Astro.request.cf`, which Cloudflare populates per request.","triggerScenarios":"In an Astro v6 + @astrojs/cloudflare project, any code accessing `Astro.locals.runtime.cf` (geo checks, bot scoring, locale negotiation) throws as soon as the getter runs.","commonSituations":"Post-upgrade v5 projects with geo/IP-based routing or analytics code; tutorials written against the old `locals.runtime` API.","solutions":["Replace `Astro.locals.runtime.cf` with `Astro.request.cf` everywhere.","Grep for `locals.runtime` to catch the sibling removals (env, caches, ctx) in the same pass.","Follow the Astro v6 upgrade notes for the Cloudflare adapter.","Stay on Astro v5 + matching adapter if you cannot migrate yet."],"exampleFix":"// before\nconst country = Astro.locals.runtime.cf.country;\n\n// after\nconst country = Astro.request.cf?.country;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"type LegacyCf = Record<string, unknown> | undefined;\nfunction safeCf(locals: App.Locals, request: Request): LegacyCf {\n  // Preferred v6 source first\n  if ('cf' in request && request.cf) return request.cf as LegacyCf;\n  const runtime = (locals as Record<string, unknown>).runtime;\n  if (!runtime || typeof runtime !== 'object') return undefined;\n  try {\n    return (runtime as { cf: unknown }).cf as LegacyCf;\n  } catch {\n    return undefined; // v6 trap — migrate callers to Astro.request.cf\n  }\n}","tryCatchPattern":null,"preventionTips":["Read request metadata from `Astro.request.cf` — it is the only supported source in v6.","Codemod `locals.runtime.cf` → `Astro.request.cf?.` (optional-chain, cf can be undefined off-Cloudflare).","Add `@cloudflare/workers-types` so request.cf is typed during migration."],"tags":["cloudflare","astro-v6","breaking-change","request-metadata","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"}