withastro/astro · error · AstroError

MissingMediaQueryDirective

MissingMediaQueryDirective

Error message

Media query not provided for `client:media` directive. A media query similar to `client:media="(max-width: 600px)"` must be provided.

What it means

The client:media directive needs a CSS media query as its value so the island knows when to hydrate. During directive extraction, if the directive is 'media' and the extracted value is not a string (bare attribute gives true, or the expression evaluates to a boolean/number/undefined), Astro throws MissingMediaQueryDirective with an example query.

Solutions

  1. Provide a media query string: client:media="(max-width: 600px)"
  2. If the value is dynamic, ensure the expression resolves to a string query, e.g. client:media={widthQuery}
  3. If you actually want always/never hydration semantics, use client:load or omit the directive instead

Example fix

// before
<Chart client:media={isMobile} />

// after
<Chart client:media="(max-width: 600px)" />
Defensive patterns

Strategy: validation

Validate before calling

// keep media queries as literal strings
<Chart client:media="(max-width: 600px)" />;
// when dynamic, validate first
if (typeof query !== 'string' || query.length === 0) throw new Error('client:media needs a query string');

Type guard

function isMediaQueryString(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0;
}

Prevention

When it happens

Trigger: Writing <Comp client:media /> with no value; passing a variable like client:media={isMobile} where isMobile is a boolean; a dynamic value that evaluates to undefined at render time.

Common situations: Assuming client:media takes a boolean toggle like some component libraries' props; wiring the directive to reactive state instead of a literal query string; template code copied from a media-query example that lost its quotes.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/d2f03a4d86ed22b7. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/runtime/server/hydration.ts:96

					extracted.hydration.directive = key.split(':')[1];
					extracted.hydration.value = value;

					// throw an error if an invalid hydration directive was provided
					if (!clientDirectives.has(extracted.hydration.directive)) {
						const hydrationMethods = Array.from(clientDirectives.keys())
							.map((d) => `client:${d}`)
							.join(', ');
						throw new Error(
							`Error: invalid hydration directive "${key}". Supported hydration methods: ${hydrationMethods}`,
						);
					}

					// throw an error if the query wasn't provided for client:media
					if (
						extracted.hydration.directive === 'media' &&
						typeof extracted.hydration.value !== 'string'
					) {
						throw new AstroError(AstroErrorData.MissingMediaQueryDirective);
					}

					break;
				}
			}
		} else {
			extracted.props[key] = value;
			if (!transitionDirectivesToCopyOnIsland.includes(key)) {
				extracted.propsWithoutTransitionAttributes[key] = value;
			}
		}
	}
	for (const sym of Object.getOwnPropertySymbols(inputProps)) {
		extracted.props[sym] = inputProps[sym];
		extracted.propsWithoutTransitionAttributes[sym] = inputProps[sym];
	}

	return extracted;

View on GitHub (pinned to 52e6c34790)