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 requires a CSS media query as its value (the directive stores `value` from the attribute). When `extractDirectives` sees `directive === 'media'` and the extracted value is not a string (missing or empty attribute), it throws `MissingMediaQueryDirective`. Astro needs the query to decide when to hydrate.

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 d081033d5f)

Solutions

  1. Provide a valid CSS media query string: `client:media="(max-width: 600px)"`.
  2. Confirm the value is quoted so Astro parses it as a string, not a boolean attribute.

Example fix

// before
<Counter client:media />

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

Strategy: validation

Validate before calling

function assertMediaQuery(value: unknown): asserts value is string {
  if (typeof value !== 'string' || value.length === 0) {
    throw new Error('client:media requires a non-empty media query string');
  }
}

Type guard

const hasMediaQuery = (v: unknown): v is string => typeof v === 'string' && v.length > 0;

Prevention

When it happens

Trigger: `<Comp client:media />` with no attribute value; `<Comp client:media="" />` with an empty string; a boolean-coerced attribute where the value resolves to non-string.

Common situations: Forgetting the query argument; assuming `client:media` hydrates at a default breakpoint; copy-paste that dropped the quoted query.

Related errors


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