{"record":{"id":"1158268204a44256","repo":"withastro/astro","slug":"you-tried-to-add-the-name-client-renderer-but","errorCode":null,"errorMessage":"You tried to add the ${name} client renderer, but its server renderer wasn't added. You must add the server renderer first. Use the `addServerRenderer` function.","messagePattern":"You tried to add the (.+?) client renderer, but its server renderer wasn't added\\. You must add the server renderer first\\. Use the `addServerRenderer` function\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/container/index.ts","lineNumber":452,"sourceCode":"\t *\n\t * const container = await AstroContainer.create();\n\t * container.addServerRenderer(reactRenderer);\n\t * container.addClientRenderer({\n\t * \tname: \"@astrojs/react\",\n\t * \tentrypoint: \"@astrojs/react/client.js\"\n\t * });\n\t * ```\n\t *\n\t * @param options {object}\n\t * @param options.name The name of the renderer. The name **isn't** arbitrary, and it should match the name of the package.\n\t * @param options.entrypoint The entrypoint of the client renderer.\n\t */\n\tpublic addClientRenderer(options: AddClientRenderer): void {\n\t\tconst { entrypoint, name } = options;\n\n\t\tconst rendererIndex = this.#manifest.renderers.findIndex((r) => r.name === name);\n\t\tif (rendererIndex === -1) {\n\t\t\tthrow new Error(\n\t\t\t\t'You tried to add the ' +\n\t\t\t\t\tname +\n\t\t\t\t\t\" client renderer, but its server renderer wasn't added. You must add the server renderer first. Use the `addServerRenderer` function.\",\n\t\t\t);\n\t\t}\n\t\tconst renderer = this.#manifest.renderers[rendererIndex];\n\t\trenderer.clientEntrypoint = entrypoint;\n\n\t\tthis.#manifest.renderers[rendererIndex] = renderer;\n\t}\n\n\t// NOTE: we keep this private via TS instead via `#` so it's still available on the surface, so we can play with it.\n\t// @ts-expect-error @ematipico: I plan to use it for a possible integration that could help people\n\tprivate static async createFromManifest(\n\t\tmanifest: SSRManifest,\n\t): Promise<experimental_AstroContainer> {\n\t\tconst container = new experimental_AstroContainer({\n\t\t\tmanifest,","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/withastro/astro/blob/3578d45d34226d63cff3d261c971c221de6794d2/packages/astro/src/container/index.ts#L434-L470","documentation":"`addClientRenderer` registers the client entrypoint used for `client:*` hydration by looking up an already-registered server renderer with the same name in the container's manifest. No renderer with that name exists yet, so the client renderer would be unreachable — the call is rejected and the message points at `addServerRenderer`.","triggerScenarios":"Calling `addClientRenderer({ name, entrypoint })` before `addServerRenderer({ name, renderer })`; using a name that does not exactly match the server renderer's name (missing `@scope/`, typo, different casing).","commonSituations":"Bootstrapping container tests that render hydrated components; copy-pasted setup where the two names drift apart ('react' vs '@astrojs/react'); ordering mistakes in test helpers.","solutions":["Register the server renderer first with the same name, then the client renderer","Make both names identical — by convention the package name, e.g. `@astrojs/react`","Load the client entrypoint from the package's `client.js` export (e.g. `import entrypoint from '@astrojs/react/client.js'`)"],"exampleFix":"// before\ncontainer.addClientRenderer({ name: '@astrojs/react', entrypoint });\ncontainer.addServerRenderer({ name: '@astrojs/react', renderer });\n\n// after\ncontainer.addServerRenderer({ name: '@astrojs/react', renderer });\ncontainer.addClientRenderer({ name: '@astrojs/react', entrypoint });","handlingStrategy":"validation","validationCode":"// track registrations yourself and enforce ordering in a helper\nconst registeredServerRenderers = new Set();\n\nfunction addRendererPair(container, name, serverRenderer, clientEntrypoint) {\n  container.addServerRenderer({ name, renderer: serverRenderer });\n  registeredServerRenderers.add(name);\n  if (clientEntrypoint) {\n    if (!registeredServerRenderers.has(name)) {\n      throw new Error(`server renderer '${name}' must be registered first`);\n    }\n    container.addClientRenderer({ name, entrypoint: clientEntrypoint });\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register server renderers before their client renderers — make one bootstrap function that does both in order","Use the exact same string (the package name) for both addServerRenderer and addClientRenderer calls","Load the client entrypoint from the package's `client.js` export rather than guessing paths"],"tags":["container","renderers","ordering","hydration","testing","experimental"],"backgroundTag":"initialization-order","analyzedSha":"3578d45d34226d63cff3d261c971c221de6794d2","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}