withastro/astro · error · Error
The renderer you passed isn't valid. A renderer is usually…
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 `check` and `renderToStaticMarkup` — the contract of an Astro server renderer. Missing either means you passed something else: the integration object, a client renderer, or the wrong export from the package.
Solutions
- Import the server entrypoint and pass it: `import renderer from '@astrojs/react/server.js'; container.addServerRenderer({ name: '@astrojs/react', renderer })`
- If writing a custom renderer, implement both `check(Component)` and `renderToStaticMarkup(Component, props, slotted)`
- Double-check you are not passing the integration object or a client renderer — only the `/server.js` export satisfies the shape
Example fix
// before
import react from '@astrojs/react';
container.addServerRenderer({ name: '@astrojs/react', renderer: react });
// after
import renderer from '@astrojs/react/server.js';
container.addServerRenderer({ name: '@astrojs/react', renderer }); Defensive patterns
Strategy: type-guard
Type guard
function isServerRenderer(value) {
return (
!!value &&
typeof value.check === 'function' &&
typeof value.renderToStaticMarkup === 'function'
);
}
if (!isServerRenderer(renderer)) {
throw new TypeError('pass the /server.js export, not the integration or client renderer');
}
container.addServerRenderer({ name, renderer }); Prevention
- Import server renderers from the package's `/server.js` entrypoint (e.g. `@astrojs/react/server.js`)
- When writing custom renderers, start from a type implementing `check` and `renderToStaticMarkup` so TypeScript catches the mistake
- Keep a single test helper that registers renderers so wrong shapes fail in one place, not across many tests
When it happens
Trigger: `addServerRenderer({ renderer: integration() })` (the integration, not its renderer); importing the package root (`@astrojs/react`) instead of `@astrojs/react/server.js`; passing a `{ entrypoint }` client-renderer shape; a hand-written renderer missing one of the two methods.
Common situations: Setting up container tests for framework components; older examples or blog posts showing different renderer shapes; wrapping/spreading a renderer and dropping its methods.
Related errors
- The renderer name must be provided when adding a server…
- You tried to add the
- Couldn't find component for route
- [astro:cache] Background revalidation failed for
- Could not find server component export
AI-assisted analysis of withastro/astro@3578d45d34 (2026-08-18).
Data as JSON: /api/errors/31f05970952dc357.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/container/index.ts:402
* 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.#manifest.renderers.push({
name: renderer.name,
ssr: renderer,
});
} else if ('name' in options) {
this.#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 3578d45d34)