withastro/astro · error · AstroError

SessionStorageSaveError

SessionStorageSaveError

Error message

The session key was not provided.

What it means

AstroSession.set() requires a non-empty string key under which the value is stored in the session map (and later serialized). The method throws SessionStorageSaveError with 'The session key was not provided.' when the key argument is falsy — empty string, undefined, or null. Storing under a falsy key would silently create unreachable data, so it is rejected immediately.

Solutions

  1. Pass a concrete non-empty string key: Astro.session.set('cart', cart).
  2. If the key is computed, default or validate it first: const key = user?.id; if (!key) return;
  3. Check for typos between the key variable name used in set() and the one you defined.

Example fix

// before
Astro.session.set(userId, { role }); // userId is undefined for anonymous visitors

// after
if (userId) {
  Astro.session.set(`user:${userId}`, { role });
}
Defensive patterns

Strategy: type-guard

Validate before calling

const key = computedKey ?? '';
if (key.length === 0) {
  throw new TypeError('session key required');
}
Astro.session.set(key, value);

Type guard

function isNonEmptySessionKey(key: unknown): key is string {
  return typeof key === 'string' && key.length > 0;
}

Prevention

When it happens

Trigger: Astro.session.set('', cart); Astro.session.set(undefined, data) (often from a typo'd variable or an optional variable at runtime); passing a computed key that evaluates to '' when its source field is missing, e.g. session.set(user.id, role) where user.id is undefined.

Common situations: Dynamic keys derived from request data (user id, locale code) that can be empty; destructuring with a renamed variable so the intended key variable is undefined; TS code bypassed with any where the key is genuinely missing.

Related errors


AI-assisted analysis of withastro/astro@3578d45d34 (2026-08-18). Data as JSON: /api/errors/4433ccd94ead7e99. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/core/session/runtime.ts:186

		}
		this.#dirty = true;
	}

	/**
	 * Sets a session value. The session is created if it does not exist.
	 */

	set<T = void, K extends string = keyof App.SessionData | (string & {})>(
		key: K,
		value: T extends void
			? K extends keyof App.SessionData
				? App.SessionData[K]
				: any
			: NoInfer<T>,
		{ ttl }: { ttl?: number } = {},
	) {
		if (!key) {
			throw new AstroError({
				...SessionStorageSaveError,
				message: 'The session key was not provided.',
			});
		}
		// save a clone of the passed in object so later updates are not
		// persisted into the store. Attempting to serialize also allows
		// us to throw an error early if needed.
		let cloned: T;
		try {
			cloned = unflatten(JSON.parse(stringify(value)));
		} catch (err) {
			throw new AstroError(
				{
					...SessionStorageSaveError,
					message: `The session data for ${key} could not be serialized.`,
					hint: 'See the devalue library for all supported types: https://github.com/rich-harris/devalue',
				},
				{ cause: err },

View on GitHub (pinned to 3578d45d34)