withastro/astro · error · AstroError
CacheNotEnabled
CacheNotEnabled
Error message
`Astro.cache` is not available because the cache feature is not enabled. To use caching, configure a cache provider in your Astro config under `cache`.
What it means
`Astro.cache.invalidate()` requires a backing cache provider to actually purge entries. The runtime `AstroCache` holds a `#provider` field that is `null` when no provider is wired up (e.g., cache disabled or misconfigured), and `invalidate` guards against a null provider by throwing `CacheNotEnabled`. This surfaces a missing-config problem at the call site rather than silently no-opping.
Source
Thrown at packages/astro/src/core/cache/runtime/cache.ts:103
get tags(): string[] {
return [...this.#tags];
}
/**
* Get the current cache options (read-only snapshot).
* Includes all accumulated options: maxAge, swr, tags, etag, lastModified.
*/
get options(): Readonly<CacheOptions> {
return {
...this.#options,
tags: this.tags,
};
}
async invalidate(input: InvalidateOptions | LiveDataEntry): Promise<void> {
if (!this.#provider) {
throw new AstroError(CacheNotEnabled);
}
let options: InvalidateOptions;
if (isLiveDataEntry(input)) {
options = { tags: input.cacheHint?.tags ?? [] };
} else {
options = input;
}
return this.#provider.invalidate(options);
}
/** @internal */
[APPLY_HEADERS](response: Response, request: Request): void {
if (this.#disabled) return;
const finalOptions: CacheOptions = { ...this.#options, tags: this.tags };
if (finalOptions.maxAge === undefined && !finalOptions.tags?.length) return;
const headers =
this.#provider?.setHeaders?.(finalOptions, request) ?? defaultSetHeaders(finalOptions);View on GitHub (pinned to d081033d5f)
Solutions
- Add a cache provider to `astro.config`: `cache: { provider: memoryCache({ ... }) }` (or your adapter's provider).
- Guard the call at the use site: `if (Astro.cache.enabled) await Astro.cache.invalidate(...)`.
- Verify the provider package is installed and resolvable (see CacheProviderNotFound if resolution fails).
Example fix
// before
await Astro.cache.invalidate({ tags: ['posts'] });
// after
if (Astro.cache.enabled) {
await Astro.cache.invalidate({ tags: ['posts'] });
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!Astro.cache.enabled) { /* skip invalidation */ } Type guard
function canInvalidate(cache) {
return cache && cache.enabled === true;
} Try / catch
try {
await Astro.cache.invalidate({ tags: ['x'] });
} catch (e) {
if (e.code === 'CacheNotEnabled') { /* degrade gracefully */ } else throw e;
} Prevention
- Always gate cache writes/invalidation behind Astro.cache.enabled.
- Centralize cache operations in a helper that checks enabled first.
- Ensure a cache provider is configured in every environment that runs invalidation code.
When it happens
Trigger: Calling `Astro.cache.invalidate({ tags: ['post-123'] })` inside a route/action handler when the `cache` key is absent from `astro.config` or when the provider failed to load. The guard at `runtime/cache.ts:103` triggers because `this.#provider` is null.
Common situations: Local dev where caching is intentionally off but invalidation code runs in a shared util; deploying with the cache config behind an environment flag that evaluates false; an adapter that does not provide a cache provider.
Related errors
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/9a4fc7d7842acef0.
Report an issue: GitHub.