withastro/astro · critical · AstroError
Setting the 'mode' option is required.
Error message
Setting the 'mode' option is required.
What it means
Thrown by the @astrojs/node adapter when its integration factory is called without a `mode` option. The adapter cannot decide whether to run as a standalone server or as Express/connect middleware, so it aborts at config setup. `mode` is a required field on UserOptions, not optional at runtime.
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 d081033d5f)
Solutions
- Set `mode: 'standalone'` in the adapter options for a normal Node HTTP server (default use case).
- Set `mode: 'middleware'` if you are mounting Astro inside an existing Express/Connect/Polka server via the exported `handler`.
- Confirm the option is on the adapter call itself: `adapter: node({ mode: 'standalone' })`, not elsewhere in the config.
Example fix
// before
import node from '@astrojs/node';
export default defineConfig({ adapter: node() });
// after
import node from '@astrojs/node';
export default defineConfig({ adapter: node({ mode: 'standalone' }) }); Defensive patterns
Strategy: type-guard
Validate before calling
import type { UserOptions } from '@astrojs/node';
function assertNodeOptions(o: Partial<UserOptions>): asserts o is UserOptions {
if (!o.mode || (o.mode !== 'standalone' && o.mode !== 'middleware')) {
throw new Error('node adapter requires mode: \'standalone\' | \'middleware\'');
}
}
assertNodeOptions(opts); Type guard
function isValidNodeMode(m: unknown): m is 'standalone' | 'middleware' {
return m === 'standalone' || m === 'middleware';
} Prevention
- Treat the adapter options object as strongly typed via `satisfies UserOptions`.
- Centralize adapter construction in one config module so mode is never omitted by a partial spread.
- Add a unit test asserting the config calls node() with a valid mode.
When it happens
Trigger: Calling `node({ /* missing mode */ })` as the `adapter` in `astro.config`. Passing `mode: undefined` or `mode: ''` (falsy) also triggers it because the guard is `if (!userOptions?.mode)`.
Common situations: Upgrading to a Node adapter major version that promoted `mode` from optional-with-default to required. Copying an old config snippet that only set `mode: 'standalone'` conditionally. Spreading a partial options object that omits the key.
Related errors
- CONTENT_TOO_LARGE
- Configured image service is not a local service
- Configured image service is not a local service
- MissingGetFontFileRequestUrl
- RemoteImageNotAllowed
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/fbd8082ed2ef932a.
Report an issue: GitHub.