dotnet/aspnetcore · error · Error
Cannot merge mismatching component descriptors
Error message
Cannot merge mismatching component descriptors:
${JSON.stringify(target)}
and
${JSON.stringify(source)} What it means
Blazor can represent a single root component with multiple marker types (e.g. a 'server' marker and a 'webassembly' marker for an 'auto' component) that must be merged into one descriptor before rendering. mergeDescriptors refuses to combine two descriptors when canMergeDescriptors returns false, i.e. their types differ or their formattedComponentKey/locationHash-based keys do not match. The throw indicates two markers that purport to describe the same component are actually incompatible.
Solutions
- Force a full page reload (clear cached prerendered HTML) so start/end markers regenerate coherently.
- Ensure only one render mode (Server, WebAssembly, or Auto) is applied to a given component instance and not mixed across requests.
- Align client (blazor.web.js) and server framework versions.
- Inspect the two JSON markers printed in the error to see which type/key field diverges and trace where the stale marker originates.
Example fix
// before: component rendered with conflicting markers from two render modes // after: declare a single render mode explicitly @rendermode InteractiveAuto // and avoid layering InteractiveServer on the same component elsewhere
Defensive patterns
Strategy: validation
Validate before calling
import { canMergeDescriptors } from './...';
// before calling mergeDescriptors:
if (!canMergeDescriptors(target, source)) {
// log the mismatch and skip, or regenerate markers via full reload
window.location.reload();
} Type guard
function descriptorsMergeable(a: any, b: any): boolean {
return a && b && a.type === b.type && doKeysMatch(a.key, b.key);
} Try / catch
try {
mergeDescriptors(target, source);
} catch (e) {
console.error('Descriptor merge failed; reloading to regenerate markers', e);
window.location.reload();
} Prevention
- Apply exactly one render mode to each component instance.
- Avoid mixing global and per-page interactivity that targets the same component.
- Align Blazor JS bundle and server versions.
- Do not serve stale prerendered fragments alongside fresh interactive renders.
When it happens
Trigger: Triggered at line 351 when canMergeDescriptors(target, source) is false — either target.type !== source.type, or doKeysMatch returns false comparing their key/formattedComponentKey/locationHash. This happens during descriptor discovery when iterating paired markers in the DOM.
Common situations: The DOM contains two component markers with the same DOM position but different component types (e.g. a leftover 'server' marker and a new 'webassembly' marker from an old/new render); mixed global+per-page interactivity on the same component; version skew between client and server marker formats; a stale fragment of prerendered HTML served alongside a fresh interactive render.
Related errors
- Cannot supply a component of type
- Could not resolve a root component with SSR component ID
- Descriptors must be assigned a renderer ID before getting…
- Dynamic root components have already been enabled.
- Dynamic root components have not been enabled in this…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/bc6b0d6f1699d76a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts:351
} as unknown as ComponentMarker;
}
function doKeysMatch(a: MarkerKey | undefined, b: MarkerKey | undefined) {
if (!a || !b) {
// Unspecified keys are never considered to be matching
return false;
}
return a.locationHash === b.locationHash && a.formattedComponentKey === b.formattedComponentKey;
}
export function canMergeDescriptors(target: ComponentDescriptor, source: ComponentDescriptor): boolean {
return target.type === source.type && doKeysMatch(target.key, source.key);
}
export function mergeDescriptors(target: ComponentDescriptor, source: ComponentDescriptor) {
if (!canMergeDescriptors(target, source)) {
throw new Error(`Cannot merge mismatching component descriptors:\n${JSON.stringify(target)}\nand\n${JSON.stringify(source)}`);
}
target.uniqueId = source.uniqueId;
if (target.type === 'webassembly' || target.type === 'auto') {
const sourceWebAssemblyData = source as WebAssemblyMarkerData;
target.parameterDefinitions = sourceWebAssemblyData.parameterDefinitions;
target.parameterValues = sourceWebAssemblyData.parameterValues;
}
if (target.type === 'server' || target.type === 'auto') {
const sourceServerData = source as ServerMarkerData;
target.sequence = sourceServerData.sequence;
target.descriptor = sourceServerData.descriptor;
}
}
export type ComponentDescriptor = ServerComponentDescriptor | WebAssemblyComponentDescriptor | AutoComponentDescriptor;View on GitHub (pinned to 3600ca084e)