dotnet/aspnetcore · error · Error
The parameter '${parameterName}' accepts a complex-typed obj
Error message
The parameter '${parameterName}' accepts a complex-typed object so it cannot be set using an attribute. Try setting it as a element property instead. What it means
Thrown unconditionally by parseAttributeValue in the 'object' case. Complex-typed (object) parameters cannot be expressed as a string attribute, so the framework refuses to parse them; the only way to supply such a parameter is via the element's JS property, which is defined in the constructor for each mapped parameter.
Source
Thrown at src/Components/CustomElements/src/js/BlazorCustomElements.ts:134
case 'false':
case 'False':
return false;
default:
throw new Error(`Invalid boolean value '${attributeValue}' for parameter '${parameterName}'`);
}
case 'number':
const number = Number(attributeValue);
if (Number.isNaN(number)) {
throw new Error(`Invalid number value '${attributeValue}' for parameter '${parameterName}'`);
} else {
return number;
}
case 'boolean?':
return attributeValue ? BlazorCustomElement.parseAttributeValue(attributeValue, 'boolean', parameterName) : null;
case 'number?':
return attributeValue ? BlazorCustomElement.parseAttributeValue(attributeValue, 'number', parameterName) : null;
case 'object':
throw new Error(`The parameter '${parameterName}' accepts a complex-typed object so it cannot be set using an attribute. Try setting it as a element property instead.`);
default:
throw new Error(`Unknown type '${type}' for parameter '${parameterName}'`);
}
}
}
function dasherize(value: string): string {
return camelCase(value).replace(/([A-Z])/g, "-$1").toLowerCase();
}
function camelCase(value: string): string {
return value[0].toLowerCase() + value.substring(1);
}
interface JSComponentParameter {
name: string;
type: JSComponentParameterType;
}View on GitHub (pinned to 294cab2f9b)
Solutions
- Set the value as a JS property: const el = document.querySelector('my-component'); el.data = { a: 1 }; — the constructor wires up a property setter per parameter (BlazorCustomElements.ts:50-65).
- Redesign the parameter as a primitive (string JSON) and parse it inside the component, if you must use an attribute.
- Split the complex parameter into multiple primitive [Parameter] properties that can each be set as attributes.
Example fix
// before (throws)
<my-chart options="{\"legend\":true}"></my-chart>
// after
const chart = document.querySelector('my-chart');
chart.options = { legend: true }; Defensive patterns
Strategy: type-guard
Validate before calling
function isComplexParamType(type: string): boolean {
return type === 'object';
}
// for each descriptor, decide attribute vs property
for (const p of parameterDescriptors) {
if (isComplexParamType(p.type)) {
el[p.name] = complexValue; // property, not attribute
} else {
el.setAttribute(dasherize(p.name), String(value));
}
} Type guard
type ComplexType = 'object';
function isObjectParam(p: { type: string }): p is { type: ComplexType } {
return p.type === 'object';
} Try / catch
try {
el.setAttribute('options', JSON.stringify(value));
} catch (e) {
if (/cannot be set using an attribute/.test((e as Error).message)) {
el.options = value; // fall back to property
} else throw e;
} Prevention
- Never bind complex parameters via attributes; use the camelCase JS property.
- Document for each custom element which parameters are 'object' so authors know to use properties.
- Redesign complex parameters as multiple primitive parameters if attribute-binding is required.
- In your binding layer, branch on the descriptor type before choosing attribute vs property.
When it happens
Trigger: Declaring a [Parameter] of a complex type (class, array, nested object) on a Razor component exposed as a custom element, and then trying to set it via an HTML attribute: <my-component data="{a:1}"/>. The framework detects type 'object' and throws.
Common situations: Components that take POCOs, lists, dictionaries, or component references as parameters and are registered via RegisterAsCustomElement. Authors naturally try attribute binding first and hit this.
Related errors
- Invalid boolean value '${attributeValue}' for parameter '${p
- Invalid number value '${attributeValue}' for parameter '${pa
- Unknown type '${type}' for parameter '${parameterName}'
- Cannot connect component ${this.localName} to the document a
- Error parsing the sequence '${sequence}' for component '${JS
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/75f99fc2175160e6.
Report an issue: GitHub.