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

  1. Pass the mode explicitly: node({ mode: 'standalone' }) for the typical self-hosted setup
  2. Use node({ mode: 'middleware' }) only when you embed the handler in your own HTTP server
  3. 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

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


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)