{"record":{"id":"92b6a75691b64edd","repo":"dotnet/aspnetcore","slug":"invalid-end-of-component-comment-json","errorCode":null,"errorMessage":"Invalid end of component comment: '${json}'","messagePattern":"Invalid end of component comment: '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts","lineNumber":288,"sourceCode":"    throw new Error('assembly must be defined when using a descriptor.');\n  }\n\n  if (!typeName) {\n    throw new Error('typeName must be defined when using a descriptor.');\n  }\n\n  // Parameter definitions and values come Base64 encoded from the server, since they contain random data and can make the\n  // comment invalid. We could unencode them in .NET Code, but that would be slower to do and we can leverage the fact that\n  // JS provides a native function that will be much faster and that we are doing this work while we are fetching\n  // blazor.boot.json\n  payload.parameterDefinitions = payload.parameterDefinitions && atob(payload.parameterDefinitions);\n  payload.parameterValues = payload.parameterValues && atob(payload.parameterValues);\n}\n\nfunction validateEndComponentPayload(json: string, prerenderId: string): void {\n  const payload = JSON.parse(json) as ComponentEndMarker;\n  if (Object.keys(payload).length !== 1) {\n    throw new Error(`Invalid end of component comment: '${json}'`);\n  }\n  const prerenderEndId = payload.prerenderId;\n  if (!prerenderEndId) {\n    throw new Error(`End of component comment must have a value for the prerendered property: '${json}'`);\n  }\n  if (prerenderEndId !== prerenderId) {\n    throw new Error(`End of component comment prerendered property must match the start comment prerender id: '${prerenderId}', '${prerenderEndId}'`);\n  }\n}\n\nclass ComponentCommentIterator {\n  private childNodes: NodeListOf<ChildNode>;\n\n  private currentIndex: number;\n\n  private length: number;\n\n  public currentElement: ChildNode | undefined;","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts#L270-L306","documentation":"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.","triggerScenarios":"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.","commonSituations":"HTML transformation injecting extra fields; version mismatch changing the end-marker schema; corrupted prerendered output; custom serializer for end markers.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isWellFormedEndMarker(json: string): boolean {\n  try {\n    const p = JSON.parse(json);\n    return Object.keys(p).length === 1 && 'prerenderId' in p;\n  } catch { return false; }\n}","typeGuard":"function isEndMarker(payload: any): payload is { prerenderId: string } {\n  return payload && Object.keys(payload).length === 1\n    && typeof payload.prerenderId === 'string' && payload.prerenderId.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Do not customize end-marker emission.","Match framework versions.","Avoid JSON-rewriting middleware on Blazor HTML."],"tags":["blazor","ssr","prerendering","markers","validation"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}