{"record":{"id":"1b16ae620ac7bc77","repo":"withastro/astro","slug":"unexpected-template-exit-instruction-without-a-mat","errorCode":null,"errorMessage":"Unexpected template-exit instruction without a matching template-enter. This may indicate that the compiler emitted unbalanced template boundaries, or that a component manually injected a template-exit render instruction.","messagePattern":"Unexpected template-exit instruction without a matching template-enter\\. This may indicate that the compiler emitted unbalanced template boundaries, or that a component manually injected a template-exit render instruction\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/runtime/server/render/common.ts","lineNumber":134,"sourceCode":"\t\t\t\t// don't mark it as deduplicated. Template content is inert, scripts\n\t\t\t\t// inside don't execute, so the script must also appear outside the\n\t\t\t\t// template for non-template instances to work\n\t\t\t\tif (result._metadata.templateDepth > 0) {\n\t\t\t\t\treturn content;\n\t\t\t\t}\n\t\t\t\tif (result._metadata.renderedScripts.has(id)) {\n\t\t\t\t\treturn '';\n\t\t\t\t}\n\t\t\t\tresult._metadata.renderedScripts.add(id);\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\tcase 'template-enter': {\n\t\t\t\tresult._metadata.templateDepth++;\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\tcase 'template-exit': {\n\t\t\t\tif (result._metadata.templateDepth <= 0) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Unexpected template-exit instruction without a matching template-enter. ' +\n\t\t\t\t\t\t\t'This may indicate that the compiler emitted unbalanced template boundaries, ' +\n\t\t\t\t\t\t\t'or that a component manually injected a template-exit render instruction.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tresult._metadata.templateDepth--;\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Unknown chunk type: ${(chunk as any).type}`);\n\t\t\t}\n\t\t}\n\t} else if (chunk instanceof Response) {\n\t\treturn '';\n\t} else if (isSlotString(chunk as string)) {\n\t\tlet out = '';\n\t\tconst c = chunk as SlotString;\n\t\t// Position-independent instructions (head, hydration, etc.) are emitted first.","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/runtime/server/render/common.ts#L116-L152","documentation":"The renderer tracks paired template-enter/template-exit render instructions (used for transition scopes) with a depth counter in result._metadata.templateDepth. A template-exit arriving when the depth is 0 means the boundaries are unbalanced: either the compiler emitted mismatched instructions, or user code manually injected a template-exit instruction into the render stream. This is an internal invariant, not a normal authoring error.","triggerScenarios":"Version skew between astro and @astrojs/compiler producing unbalanced instructions; calling internal render APIs (createRenderInstruction) to emit template-exit manually; plugins that transform or reorder compiled .astro output and drop a template-enter.","commonSituations":"Partial upgrades where the lockfile kept an old @astrojs/compiler; forks/patches of the compiler; exotic integrations that re-emit render chunks. Ordinary projects essentially never see this.","solutions":["Align versions: reinstall dependencies so astro and @astrojs/compiler match the same release","Remove any code that manually injects render instructions into the stream","Disable plugins that transform compiled .astro output and retest","If it persists on clean versions, open an Astro issue with a minimal reproduction"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const stream = await renderPage(request);\n} catch (err) {\n  if (String(err).includes('template-exit instruction')) {\n    // compiler/runtime mismatch — capture versions and rebuild rather than retry\n    console.error('astro/@astrojs/compiler versions:', process.env.ASTRO_VERSION);\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Keep astro and @astrojs/compiler versions locked to the same release in your lockfile","Never inject internal render instructions (createRenderInstruction) into rendered output yourself","Re-run a clean install after major Astro upgrades"],"tags":["astro","compiler","internal-invariant","render-instructions","view-transitions"],"backgroundTag":"compiler-unbalanced-output","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}