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

  1. Add a cache provider to `astro.config`: `cache: { provider: memoryCache({ ... }) }` (or your adapter's provider).
  2. Guard the call at the use site: `if (Astro.cache.enabled) await Astro.cache.invalidate(...)`.
  3. 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

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.