withastro/astro · error · Error
Astro.locals.runtime.caches has been removed in Astro v6…
Error message
Astro.locals.runtime.caches has been removed in Astro v6. Use the global 'caches' object instead.
What it means
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.
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.
Example fix
// before const cached = await Astro.locals.runtime.caches.default.match(req); // after const cached = await caches.default.match(req);
Defensive patterns
Strategy: type-guard
Type guard
declare const caches: CacheStorage; // from @cloudflare/workers-types
function safeCaches(locals: App.Locals): CacheStorage | undefined {
if (typeof caches !== 'undefined') return caches; // workerd global (preferred in v6)
const runtime = (locals as Record<string, unknown>).runtime;
if (!runtime || typeof runtime !== 'object') return undefined;
try {
return (runtime as { caches: unknown }).caches as CacheStorage;
} catch {
return undefined; // v6 trap — callers must use the global `caches`
}
} Prevention
- 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.
When it happens
Trigger: Code such as `Astro.locals.runtime.caches.default.match(...)` executing in an Astro v6 Cloudflare project throws immediately from the trap getter.
Common situations: Cached-response or edge-cache tag logic written for Astro v5 being carried into v6; shared components reused across adapter versions.
Related errors
- Astro.locals.runtime.cf has been removed in Astro v6. Use…
- Astro.locals.runtime.ctx has been removed in Astro v6. Use…
- Astro.locals.runtime.env has been removed in Astro v6. Use…
- LegacyContentConfigError
- A content collection is defined with legacy features (e.g…
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/abaf6860a028f359.
Report an issue: GitHub.
Appendix: source
Thrown at packages/integrations/cloudflare/src/utils/cf-helpers.ts:82
export function createLocals(ctx: ExecutionContext): Runtime {
const locals: Runtime = {
cfContext: ctx,
};
Object.defineProperty(locals, 'runtime', {
enumerable: false,
value: {
get env(): never {
throw new Error(
`Astro.locals.runtime.env has been removed in Astro v6. Use 'import { env } from "cloudflare:workers"' instead.`,
);
},
get cf(): never {
throw new Error(
`Astro.locals.runtime.cf has been removed in Astro v6. Use 'Astro.request.cf' instead.`,
);
},
get caches(): never {
throw new Error(
`Astro.locals.runtime.caches has been removed in Astro v6. Use the global 'caches' object instead.`,
);
},
get ctx(): never {
throw new Error(
`Astro.locals.runtime.ctx has been removed in Astro v6. Use 'Astro.locals.cfContext' instead.`,
);
},
},
});
return locals;
}
/**
* Extracts the client IP address from the `cf-connecting-ip` header.
*/
export function getClientAddress(request: Request): string | undefined {
return getValidatedIpFromHeader(request.headers.get('cf-connecting-ip'));View on GitHub (pinned to 52e6c34790)