withastro/astro · error · Error
The renderer you passed isn't valid. A renderer is usually a
Error message
The renderer you passed isn't valid. A renderer is usually an object that exposes the `check` and `renderToStaticMarkup` functions. Usually, the renderer is exported by a /server.js entrypoint e.g. `import renderer from '@astrojs/react/server.js'`
What it means
`experimental_AstroContainer.addServerRenderer` validates that the passed renderer object exposes both a `check` and a `renderToStaticMarkup` function — the two methods Astro's SSR pipeline calls to detect and render a framework component. Missing either makes the renderer unusable, so the container rejects it immediately.
Source
Thrown at packages/astro/src/container/index.ts:375
* import reactRenderer from "@astrojs/react/server.js";
* import vueRenderer from "@astrojs/vue/server.js";
* import customRenderer from "../renderer/customRenderer.js";
* import { experimental_AstroContainer as AstroContainer } from "astro/container"
*
* const container = await AstroContainer.create();
* container.addServerRenderer(reactRenderer);
* container.addServerRenderer(vueRenderer);
* container.addServerRenderer("customRenderer", customRenderer);
* ```
*
* @param options {object}
* @param options.name The name of the renderer. The name **isn't** arbitrary, and it should match the name of the package.
* @param options.renderer The server renderer exported by integration.
*/
public addServerRenderer(options: AddServerRenderer): void {
const { renderer } = options;
if (!renderer.check || !renderer.renderToStaticMarkup) {
throw new Error(
"The renderer you passed isn't valid. A renderer is usually an object that exposes the `check` and `renderToStaticMarkup` functions.\n" +
"Usually, the renderer is exported by a /server.js entrypoint e.g. `import renderer from '@astrojs/react/server.js'`",
);
}
if (isNamedRenderer(renderer)) {
this.#pipeline.manifest.renderers.push({
name: renderer.name,
ssr: renderer,
});
} else if ('name' in options) {
this.#pipeline.manifest.renderers.push({
name: options.name,
ssr: renderer,
});
} else {
throw new Error(
'The renderer name must be provided when adding a server renderer that is not a named renderer.',
);View on GitHub (pinned to d081033d5f)
Solutions
- Import the renderer from its documented server entrypoint, e.g. `import reactRenderer from '@astrojs/react/server.js'`.
- Confirm the object has both `check` and `renderToStaticMarkup` functions before passing it.
- If writing a custom renderer, implement both methods on the exported object.
- Check the renderer package's `package.json#exports` for the correct `server` subpath for your version.
Example fix
// before
import react from '@astrojs/react';
container.addServerRenderer({ renderer: react });
// after
import reactRenderer from '@astrojs/react/server.js';
container.addServerRenderer(reactRenderer); Defensive patterns
Strategy: type-guard
Validate before calling
function isValidRenderer(r) {
return r && typeof r.check === 'function' && typeof r.renderToStaticMarkup === 'function';
}
if (!isValidRenderer(renderer)) throw new Error('renderer missing check/renderToStaticMarkup'); Type guard
function isValidServerRenderer(r): r is { check: Function; renderToStaticMarkup: Function } {
return !!r && typeof r.check === 'function' && typeof r.renderToStaticMarkup === 'function';
} Prevention
- Always import renderers from the documented `/server.js` subpath.
- Validate a renderer object before passing it to `addServerRenderer`.
- Implement both `check` and `renderToStaticMarkup` on custom renderers.
When it happens
Trigger: Calling `container.addServerRenderer({ renderer: someObj })` where `someObj` lacks `check` or `renderToStaticMarkup`; importing the wrong entrypoint (e.g. the client `client.js` instead of `server.js`); passing a default-export wrapper object instead of the renderer itself.
Common situations: Importing from the package root rather than the `/server.js` subpath; passing a hand-written partial renderer for testing; version mismatch where a renderer integration changed its export shape; tree-shaking/TypeScript `import type` stripping a side-effect-only export.
Related errors
- The renderer name must be provided when adding a server rend
- You tried to add the ${name} client renderer, but its server
- Couldn't find component for route ${routeData.pathname}
- Unable to render ${metadata.displayName}! This component li
- ActionCalledFromServerError
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/31f05970952dc357.
Report an issue: GitHub.