dotnet/aspnetcore · error · Error

Unknown type '${type}' for parameter '${parameterName}'

Error message

Unknown type '${type}' for parameter '${parameterName}'

What it means

Thrown by parseAttributeValue's default branch when the parameter's declared JSComponentParameterType is none of 'string','boolean','boolean?','number','number?','object'. This is a registration-time contract violation: the type metadata supplied to RegisterAsCustomElement contains an unrecognized type identifier.

Source

Thrown at src/Components/CustomElements/src/js/BlazorCustomElements.ts:136

            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;
}

// JSON-primitive types, plus for those whose .NET equivalent isn't nullable, a '?' to indicate nullability

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Map every non-primitive parameter to 'object' and set it via the JS property (object is the catch-all for complex types).
  2. Map Date/Time/DateTimeOffset parameters to 'string' (ISO 8601) and parse on the .NET side, or use a string [Parameter].
  3. Ensure you are using a matching pair of .NET runtime and JS custom-elements bundle so the type vocabulary agrees.
  4. Inspect the JSComponentParameter[] passed to RegisterAsCustomElement and confirm every entry's 'type' is one of the six supported literals.

Example fix

// before: descriptor with unsupported type
RegisterAsCustomElement('my-comp', [
  { name: 'Created', type: 'date' } // unsupported
]);

// after: use 'string' for dates
RegisterAsCustomElement('my-comp', [
  { name: 'Created', type: 'string' }
]);
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set(['string', 'boolean', 'boolean?', 'number', 'number?', 'object']);
function validateDescriptors(params: { name: string; type: string }[]) {
  for (const p of params) {
    if (!SUPPORTED.has(p.type)) {
      throw new Error(`Unsupported parameter type '${p.type}' for '${p.name}'. Use one of: ${[...SUPPORTED].join(', ')}`);
    }
  }
}
validateDescriptors(parameterDescriptors);

Type guard

type SupportedType = 'string' | 'boolean' | 'boolean?' | 'number' | 'number?' | 'object';
function isSupportedType(t: string): t is SupportedType {
  return ['string', 'boolean', 'boolean?', 'number', 'number?', 'object'].includes(t);
}

Try / catch

// Thrown synchronously inside attributeChangedCallback; catch at the dispatcher.
try {
  el.setAttribute(p.name, raw);
} catch (e) {
  if (/Unknown type/.test((e as Error).message)) {
    console.error('Descriptor type mismatch — regenerate JSComponentParameter metadata');
  } else throw e;
}

Prevention

When it happens

Trigger: Registering a custom element whose parameter descriptors include an unsupported type string (e.g. 'date', 'array', 'int', 'guid', a custom enum). The attribute parser has no branch for it and falls through to default.

Common situations: Hand-crafting JSComponentParameter[] metadata incorrectly, a version mismatch where newer parameter types are forwarded to an older JS runtime that doesn't know them, or a serializer that emitted the C# type name instead of the expected JSON-primitive alias.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/339e4793e78173bd. Report an issue: GitHub.