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
- Provide a media query string: client:media="(max-width: 600px)"
- If the value is dynamic, ensure the expression resolves to a string query, e.g. client:media={widthQuery}
- 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
- Always quote the query: client:media="(max-width: 600px)"
- Never pass booleans or numbers to client:media
- For dynamic queries, derive the string from state (e.g. media={table of queries}) and type it as string
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
- Error: invalid hydration directive
- NoClientOnlyHint
- NoMatchingImport
- NoMatchingRenderer
- You are attempting to render <
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)