dotnet/aspnetcore · error · Error
Invalid end of component comment
Error message
Invalid end of component comment: '${json}' What it means
Thrown by validateEndComponentPayload when the parsed end-of-component comment JSON has more or fewer than exactly one key. The end marker must contain only the single 'prerenderId' property; any extra or missing keys mean the payload is malformed. This is the first structural check on the closing marker before prerenderId is validated.
Solutions
- Inspect the served HTML: the end comment must be a JSON object with exactly one key, prerenderId.
- Remove HTML post-processing that alters Blazor comment JSON.
- Ensure the prerendering pipeline emits the correct end marker shape.
- Align server and client Blazor runtime versions.
Defensive patterns
Strategy: validation
Validate before calling
function assertEndMarkerShape(payload: any) {
const keys = Object.keys(payload ?? {});
if (keys.length !== 1 || keys[0] !== 'prerenderId') {
throw new Error(`Invalid end marker; expected exactly { prerenderId }, got ${JSON.stringify(payload)}`);
}
} Type guard
function isEndMarker(p: any): p is { prerenderId: string } {
return p !== null && typeof p === 'object' && Object.keys(p).length === 1 && typeof p.prerenderId === 'string';
} Prevention
- Ensure the prerendering pipeline emits end comments as { prerenderId } only.
- Disable HTML transforms that alter comment JSON.
- Validate end-marker shape in CI HTML assertions.
When it happens
Trigger: An end component comment whose JSON has zero keys (empty object) or two+ keys; a transform that added/removed fields; a start marker accidentally used as an end marker.
Common situations: HTML minifier that strips or rewrites the end comment; a copy-paste error placing a start-comment payload where the end comment should be; version skew producing a different end-marker schema; corruption.
Related errors
- assembly must be defined when using a descriptor.
- Could not find an end component comment for
- descriptor must be defined when using a descriptor.
- Error parsing the sequence
- Found malformed component comment at
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/92b6a75691b64edd.
Report an issue: GitHub.
Appendix: 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 3600ca084e)