{"record":{"id":"94eee2c8c2c52a18","repo":"withastro/astro","slug":"astro-locals-runtime-ctx-has-been-removed-in-astro","errorCode":null,"errorMessage":"Astro.locals.runtime.ctx has been removed in Astro v6. Use 'Astro.locals.cfContext' instead.","messagePattern":"Astro\\.locals\\.runtime\\.ctx has been removed in Astro v6\\. Use 'Astro\\.locals\\.cfContext' instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/cloudflare/src/utils/cf-helpers.ts","lineNumber":87,"sourceCode":"\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'));\n}\n","sourceCodeStart":69,"sourceCodeEnd":102,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/integrations/cloudflare/src/utils/cf-helpers.ts#L69-L102","documentation":"Last of the Astro v6 removals: `Astro.locals.runtime.ctx` (the ExecutionContext with waitUntil, passThroughOnException, caches accessor) is gone. The trap getter throws and points to the replacement, `Astro.locals.cfContext`, which the v6 adapter populates with the same ExecutionContext.","triggerScenarios":"Calling `Astro.locals.runtime.ctx.waitUntil(...)` (analytics beacons, deferred cache fills) in an Astro v6 project throws the moment the getter executes.","commonSituations":"Deferred-work patterns from Astro v5 projects; code copied from older Cloudflare adapter docs that used locals.runtime.ctx.","solutions":["Replace `Astro.locals.runtime.ctx` with `Astro.locals.cfContext`.","Update the App.Locals type to declare `cfContext: ExecutionContext` for type safety.","Sweep for the other removed properties (env, cf, caches) at the same time.","Remain on Astro v5 with the matching adapter if migration must wait."],"exampleFix":"// before\nAstro.locals.runtime.ctx.waitUntil(sendAnalytics());\n\n// after\nAstro.locals.cfContext.waitUntil(sendAnalytics());","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"interface CfLocals extends App.Locals {\n  cfContext?: ExecutionContext;\n}\nfunction safeExecContext(locals: App.Locals): ExecutionContext | undefined {\n  const v6 = (locals as CfLocals).cfContext;\n  if (v6) return v6;\n  const runtime = (locals as Record<string, unknown>).runtime;\n  if (!runtime || typeof runtime !== 'object') return undefined;\n  try {\n    return (runtime as { ctx: unknown }).ctx as ExecutionContext;\n  } catch {\n    return undefined; // v6 trap — migrate to Astro.locals.cfContext\n  }\n}","tryCatchPattern":null,"preventionTips":["Extend App.Locals to declare `cfContext: ExecutionContext` so TS flags old `runtime.ctx` reads.","Centralize waitUntil usage in one helper instead of scattering locals access across pages.","Migrate all four removed properties (env/cf/caches/ctx) in a single upgrade pass to avoid repeat breakage."],"tags":["cloudflare","astro-v6","breaking-change","execution-context","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"}