dotnet/aspnetcore · error
Invalid end of component comment: '${json}'
Error message
Invalid end of component comment: '${json}' What it means
Thrown by validateEndComponentPayload (ComponentDescriptorDiscovery.ts:288) when an end marker's parsed JSON object does not have exactly one key. The end marker must contain only the 'prerenderId' key; any extra or missing keys indicate the end comment is malformed.
Source
Thrown at src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts:288
throw new Error('assembly must be defined when using a descriptor.');
}
if (!typeName) {
throw new Error('typeName must be defined when using a descriptor.');
}
// Parameter definitions and values come Base64 encoded from the server, since they contain random data and can make the
// comment invalid. We could unencode them in .NET Code, but that would be slower to do and we can leverage the fact that
// JS provides a native function that will be much faster and that we are doing this work while we are fetching
// blazor.boot.json
payload.parameterDefinitions = payload.parameterDefinitions && atob(payload.parameterDefinitions);
payload.parameterValues = payload.parameterValues && atob(payload.parameterValues);
}
function validateEndComponentPayload(json: string, prerenderId: string): void {
const payload = JSON.parse(json) as ComponentEndMarker;
if (Object.keys(payload).length !== 1) {
throw new Error(`Invalid end of component comment: '${json}'`);
}
const prerenderEndId = payload.prerenderId;
if (!prerenderEndId) {
throw new Error(`End of component comment must have a value for the prerendered property: '${json}'`);
}
if (prerenderEndId !== prerenderId) {
throw new Error(`End of component comment prerendered property must match the start comment prerender id: '${prerenderId}', '${prerenderEndId}'`);
}
}
class ComponentCommentIterator {
private childNodes: NodeListOf<ChildNode>;
private currentIndex: number;
private length: number;
public currentElement: ChildNode | undefined;View on GitHub (pinned to 294cab2f9b)
Solutions
- Inspect the end comment's raw JSON and confirm it has exactly {"prerenderId":"<id>"}.
- Match framework versions and avoid custom end-marker generation.
- Remove middleware that rewrites JSON inside HTML comments.
- Ensure prerendering completes without exceptions that abort the end marker.
Defensive patterns
Strategy: validation
Validate before calling
function isWellFormedEndMarker(json: string): boolean {
try {
const p = JSON.parse(json);
return Object.keys(p).length === 1 && 'prerenderId' in p;
} catch { return false; }
} Type guard
function isEndMarker(payload: any): payload is { prerenderId: string } {
return payload && Object.keys(payload).length === 1
&& typeof payload.prerenderId === 'string' && payload.prerenderId.length > 0;
} Prevention
- Do not customize end-marker emission.
- Match framework versions.
- Avoid JSON-rewriting middleware on Blazor HTML.
When it happens
Trigger: An end comment <!--Blazor:{...}--> whose JSON parses to an object with 0 or 2+ keys (e.g. {prerenderId:'x', extra:1} or {}). Typically a hand-edited or rewritten end comment.
Common situations: HTML transformation injecting extra fields; version mismatch changing the end-marker schema; corrupted prerendered output; custom serializer for end markers.
Related errors
- End of component comment must have a value for the prerender
- End of component comment prerendered property must match the
- Could not find an end component comment for '${start}'.
- Found malformed component comment at ${candidateStart.textCo
- Invalid component type '${type}'.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/92b6a75691b64edd.
Report an issue: GitHub.