withastro/astro · error · Error
The " " integration is trying to add middleware but did not…
Error message
The "${integration.name}" integration is trying to add middleware but did not specify an order. What it means
Integrations can contribute middleware that runs before or after application middleware via `addMiddleware({ order, entrypoint })`. Astro stores these in slots keyed by order (`pre` and `post`); the callback throws this plain Error when `updatedSettings.middlewares[order]` is undefined - i.e. `order` is missing or is anything other than the literal strings 'pre' and 'post'.
Solutions
- Pass order: 'pre' (runs before app middleware) or order: 'post' (runs after), exactly lowercase.
- If the integration is third-party, update it or file an issue - the call site is inside the integration.
- Type the argument ({ order, entrypoint }: { order: 'pre' | 'post'; entrypoint: string | URL }) so mistakes surface at compile time.
Example fix
// before
addMiddleware({ entrypoint: 'my-integration/middleware.js' }); // no order
// after
addMiddleware({ order: 'pre', entrypoint: 'my-integration/middleware.js' }); Defensive patterns
Strategy: validation
Validate before calling
// inside an integration, before addMiddleware
const order = input.order as string | undefined;
if (order !== 'pre' && order !== 'post') {
throw new Error('addMiddleware order must be exactly pre or post');
}
addMiddleware({ order, entrypoint }); Type guard
function isMiddlewareOrder(o: unknown): o is 'pre' | 'post' {
return o === 'pre' || o === 'post';
} Prevention
- Type the options as { order: 'pre' | 'post'; entrypoint: string | URL }.
- Remember order is lowercase and case-sensitive.
- Test the setup hook with both orders so a bad value fails in CI, not in users' projects.
When it happens
Trigger: Calling addMiddleware({ entrypoint }) with no order; passing order: 'before', 'first', 'after' or any other string; building the options object dynamically so order ends up undefined.
Common situations: Authoring an integration that injects middleware and misremembering the API; copy-pasting from docs of other frameworks where order values differ; typos like 'Post' (case-sensitive).
Related errors
- Integration has an unnamed renderer.
- Integration is injecting a type that does not end with
- Renderer does not provide a serverEntrypoint.
- The " " integration is trying to add the " " client…
- App entrypoint must default export an object.
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/159737bb902df389.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/integrations/hooks.ts:287
},
addDevToolbarApp: (entrypoint) => {
updatedSettings.devToolbarApps.push(entrypoint);
},
addClientDirective: ({ name, entrypoint }) => {
if (updatedSettings.clientDirectives.has(name) || addedClientDirectives.has(name)) {
throw new Error(
`The "${integration.name}" integration is trying to add the "${name}" client directive, but it already exists.`,
);
}
// TODO: this should be performed after astro:config:done
addedClientDirectives.set(
name,
buildClientDirectiveEntrypoint(name, entrypoint, settings.config.root),
);
},
addMiddleware: ({ order, entrypoint }) => {
if (typeof updatedSettings.middlewares[order] === 'undefined') {
throw new Error(
`The "${integration.name}" integration is trying to add middleware but did not specify an order.`,
);
}
logger.debug(
'middleware',
`The integration ${integration.name} has added middleware that runs ${
order === 'pre' ? 'before' : 'after'
} any application middleware you define.`,
);
updatedSettings.middlewares[order].push(
typeof entrypoint === 'string' ? entrypoint : fileURLToPath(entrypoint),
);
},
createCodegenDir: () => {
const codegenDir = new URL(normalizeCodegenDir(integration.name), settings.dotAstroDir);
fs.mkdirSync(codegenDir, { recursive: true });
return codegenDir;
},View on GitHub (pinned to 52e6c34790)