dotnet/aspnetcore · error · Error

Invalid boolean value

Error message

Invalid boolean value '${attributeValue}' for parameter '${parameterName}'

What it means

Thrown by BlazorCustomElement.parseAttributeValue when a custom-element attribute declared as type 'boolean' receives a value that is not exactly 'true', 'True', 'false', or 'False'. The parser is case-specific (only the leading-T variants are accepted) and rejects empty strings, '1'/'0', and any other truthy/falsy spelling.

Solutions

  1. Use one of the four accepted spellings: 'true', 'True', 'false', 'False' as the attribute string.
  2. For presence-style boolean attributes, set the value to 'true'/'false' explicitly rather than relying on the empty-string shorthand.
  3. If the value comes from data binding, coerce it before assignment: value ? 'true' : 'false'.
  4. If you need to pass a nullable or tri-state value, declare the parameter as 'boolean?' on the JS side so empty values map to null.

Example fix

<!-- before -->
<my-counter disabled></my-counter>
<my-counter enabled="1"></my-counter>

<!-- after -->
<my-counter disabled="true"></my-counter>
<my-counter enabled="true"></my-counter>
Defensive patterns

Strategy: validation

Validate before calling

// Coerce before setting an attribute that maps to a boolean parameter.
function toBooleanAttr(value) {
  const s = String(value).trim();
  if (s === 'true' || s === 'True' || s === 'false' || s === 'False') return s;
  // fall back to canonical spelling
  return value ? 'true' : 'false';
}
el.setAttribute('enabled', toBooleanAttr(rawValue));

Type guard

function isValidBooleanAttr(v) {
  return v === 'true' || v === 'True' || v === 'false' || v === 'False';
}

Try / catch

try {
  el.setAttribute('enabled', raw);
} catch (e) {
  if (/Invalid boolean value/.test(e.message)) {
    el.setAttribute('enabled', raw ? 'true' : 'false');
  } else throw e;
}

Prevention

When it happens

Trigger: Setting an HTML attribute on a Blazor custom element whose [Parameter] is bool, with a value like "", "1", "0", "yes", "TRUE", or "Disabled". Triggered both by static markup and by attributeChangedCallback after setAttribute at runtime.

Common situations: HTML boolean attributes written minimally (e.g. <my-comp disabled>) yield attribute value ""; passing "1"/"0" from data-binding code; case differences like "TRUE"; binding a non-bool model field to a bool parameter.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/f37f825ee244825b. Report an issue: GitHub.

Appendix: source

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

        await setParametersPromise;
      }
    }
  }

  static parseAttributeValue(attributeValue: string, type: JSComponentParameterType, parameterName: string): any {
    switch (type) {
      case 'string':
        return attributeValue;
      case 'boolean':
        switch (attributeValue) {
          case 'true':
          case 'True':
            return true;
          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}'`);
    }
  }

View on GitHub (pinned to 3600ca084e)