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

  1. Set `mode: 'standalone'` in the adapter options for a normal Node HTTP server (default use case).
  2. Set `mode: 'middleware'` if you are mounting Astro inside an existing Express/Connect/Polka server via the exported `handler`.
  3. 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

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


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/fbd8082ed2ef932a. Report an issue: GitHub.