withastro/astro · error · AstroError
Setting the 'mode' option is required.
Error message
Setting the 'mode' option is required.
What it means
The @astrojs/node adapter must know whether it serves the app itself (standalone, its own HTTP server) or plugs into an existing one (middleware exporting a handler). createIntegration throws immediately at config load if the options object is missing or has no truthy mode.
Solutions
- Pass the mode explicitly: node({ mode: 'standalone' }) for the typical self-hosted setup
- Use node({ mode: 'middleware' }) only when you embed the handler in your own HTTP server
- Check the options object for typos and make sure it is actually passed to node()
Example fix
// before
integrations: [node()]
// after
integrations: [node({ mode: 'standalone' })] Defensive patterns
Strategy: validation
Validate before calling
const nodeOptions: UserOptions = {
...(env === 'embedded' ? { mode: 'middleware' as const } : { mode: 'standalone' as const }),
};
if (!nodeOptions.mode) throw new Error('node adapter mode must be set');
integrations: [node(nodeOptions)] Type guard
type NodeAdapterMode = 'standalone' | 'middleware';
function isNodeAdapterMode(v: unknown): v is NodeAdapterMode {
return v === 'standalone' || v === 'middleware';
} Prevention
- Always write node({ mode: ... }) explicitly in astro.config
- Treat mode as a required deployment decision, not an optional tweak
- Add a config validation step in CI that imports the config and fails fast
When it happens
Trigger: Adding node() with no arguments to astro.config integrations; passing { mode: undefined } or a typo'd key like { mode: 'standalone' } spelled differently ({ modes: ... }); constructing the options object conditionally so mode ends up undefined.
Common situations: Copy-pasted config snippets that omit mode; refactors that made options optional; switching from another adapter whose integration takes no required options.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- `Astro.session` was accessed but no session storage is…
- [preview] No adapter found.
- The adapter has deprecated its support for " ", and future…
- The adapter has limited support for " ". Certain features…
- The adapter provides experimental support for " ". You may…
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/fbd8082ed2ef932a.
Report an issue: GitHub.
Appendix: source
Thrown at packages/integrations/node/src/index.ts:34
adapterFeatures: {
buildOutput: 'server',
middlewareMode: 'classic',
staticHeaders,
},
supportedAstroFeatures: {
hybridOutput: 'stable',
staticOutput: 'stable',
serverOutput: 'stable',
sharpImageService: 'stable',
i18nDomains: 'experimental',
envGetSecret: 'stable',
},
};
}
export default function createIntegration(userOptions: UserOptions): AstroIntegration {
if (!userOptions?.mode) {
throw new AstroError(`Setting the 'mode' option is required.`);
}
let _config: AstroConfig | undefined = undefined;
let _routeToHeaders: RouteToHeaders | undefined = undefined;
return {
name: '@astrojs/node',
hooks: {
'astro:config:setup': async ({ updateConfig, config, logger, command }) => {
let session = config.session;
_config = config;
if (session !== false && !session?.driver) {
logger.info('Enabling sessions with filesystem storage');
session = {
driver: sessionDrivers.fsLite({
base: fileURLToPath(new URL('sessions', config.cacheDir)),
}),
cookie: session?.cookie,
ttl: session?.ttl,View on GitHub (pinned to 52e6c34790)