withastro/astro · warning

Your project uses ${feature}, but your custom src/fetch.ts d

Error message

Your project uses ${feature}, but your custom src/fetch.ts does not call the ${feature}() handler. This feature will not work unless your fetch handler calls it.

What it means

A custom src/fetch.ts replaces Astro's entire request pipeline. After the first request, Astro compares features the manifest says the project uses (redirects, sessions, actions, middleware, i18n when strategy is not 'manual', cache) against the feature bitmask your handler actually invoked, and warns once for each feature whose handler was never called — that feature silently stops working under your handler.

Source

Thrown at packages/astro/src/core/app/base.ts:520

		}
		if (manifest.sessionConfig && !(used & FetchFeatures.sessions)) {
			missing.push('sessions');
		}
		if (manifest.actions && !(used & FetchFeatures.actions)) {
			missing.push('actions');
		}
		if (manifest.middleware && !(used & FetchFeatures.middleware)) {
			missing.push('middleware');
		}
		if (manifest.i18n && manifest.i18n.strategy !== 'manual' && !(used & FetchFeatures.i18n)) {
			missing.push('i18n');
		}
		if (manifest.cacheConfig && !(used & FetchFeatures.cache)) {
			missing.push('cache');
		}

		for (const feature of missing) {
			this.logger.warn(
				'router',
				`Your project uses ${feature}, but your custom src/fetch.ts does not call the ${feature}() handler. ` +
					`This feature will not work unless your fetch handler calls it.`,
			);
		}
	}

	getDefaultStatusCode(routeData: RouteData, pathname: string): number {
		return getDefaultStatusCode(this.manifest, routeData, pathname);
	}

	public getManifest() {
		return this.manifest;
	}

	logThisRequest({
		pathname,
		method,

View on GitHub (pinned to 157c500c38)

Solutions

  1. In src/fetch.ts, wrap your dispatch with the feature handlers the warning names, e.g. cache(state, () => middleware(state, ...)) and post-process the response with i18n(state, response)
  2. Or extend the default pipeline instead of replacing it, so all handlers keep running
  3. If you intentionally dropped a feature, remove its source (e.g. delete src/middleware.ts, drop the cache config) so the manifest no longer reports it as used

Example fix

// before — src/fetch.ts replaces the pipeline; middleware/i18n/cache never run
export default async function fetch(request: Request): Promise<Response> {
  return myCustomRouter(request);
}

// after — compose the handlers the warning lists
import { cache, i18n, middleware } from 'astro/fetch';

export default async function fetch(request: Request): Promise<Response> {
  const state = getFetchState(request);
  return cache(state, async () => {
    const response = await middleware(state, () => myCustomRouter(request));
    return i18n(state, response);
  });
}
Defensive patterns

Strategy: validation

Validate before calling

// after adding src/fetch.ts, assert configured features still run.
// example: middleware sets this header on every response
const res = await fetch('http://localhost:4321/');
if (!res.headers.get('x-ran-middleware')) {
  throw new Error('custom fetch.ts does not call the middleware() handler');
}

Prevention

When it happens

Trigger: Adding src/middleware.ts, session config, actions, i18n config with strategy != 'manual', or `cache`/`routeRules` config while the custom src/fetch.ts default export never calls the corresponding middleware(), i18n(), cache(), sessions(), redirects(), actions() handlers that the built-in DefaultFetchHandler pipeline composes.

Common situations: Adopting a custom fetch handler to run edge-platform or Hono-style routing logic and forgetting to compose Astro's built-in feature handlers; porting an old handler to a project that later gained middleware or caching.

Related errors


AI-assisted analysis of withastro/astro@157c500c38 (2026-08-18). Data as JSON: /api/errors/5e57b041ff59210e. Report an issue: GitHub.