yiisoft/yii2 · error · InvalidArgumentException

Unsupported type '{type}'

Error message

Unsupported type '{type}'

What it means

Thrown by AttributeTypecastBehavior::typecastValue() when $type is a scalar (string) that matches none of the supported type names — 'integer', 'float', 'boolean', 'string' (the class TYPE_* constants) — and, on PHP 8.1+, is not the class name of a BackedEnum subclass. Any other scalar type string is rejected; non-scalar types are treated as callables and dispatched via call_user_func() instead.

Source

Thrown at framework/behaviors/AttributeTypecastBehavior.php:282

                case self::TYPE_FLOAT:
                    return (float) $value;
                case self::TYPE_BOOLEAN:
                    return (bool) $value;
                case self::TYPE_STRING:
                    if (is_float($value)) {
                        return StringHelper::floatToString($value);
                    }
                    return (string) $value;
            }

            if (PHP_VERSION_ID >= 80100 && is_subclass_of($type, \BackedEnum::class)) {
                if ($value instanceof $type) {
                    return $value;
                }
                return $type::from($value);
            }

            throw new InvalidArgumentException("Unsupported type '{$type}'");
        }

        return call_user_func($type, $value);
    }

    /**
     * Composes default value for [[attributeTypes]] from the owner validation rules.
     *
     * Validators that have a [[\yii\validators\Validator::$when|when]] condition are ignored: the detection
     * result is composed once per owner class, while such a condition can only be resolved against a particular
     * model instance at validation time. Type-casting an attribute whose rule may not even be applied would
     * convert a value that has never been validated, so attributes covered by conditional rules only are left
     * out of the map. Specify [[attributeTypes]] explicitly if you need them to be type-casted.
     *
     * @return array attribute type map.
     */
    protected function detectAttributeTypes()
    {

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Use only the supported names or, better, the class constants: AttributeTypecastBehavior::TYPE_INTEGER, TYPE_FLOAT, TYPE_BOOLEAN, TYPE_STRING.
  2. For custom conversions, pass a callable instead of a string: 'attributeTypes' => ['status' => fn($v) => (int) $v].
  3. For enum casting, use a backed enum (enum Status: string) on PHP 8.1+ and give its FQCN as the type.
  4. Check for typos/shorthands ('int', 'bool', 'double') in the attributeTypes config.

Example fix

// before
'attributeTypes' => [
    'count' => 'int',        // unsupported shorthand
    'active' => 'bool',      // unsupported shorthand
    'status' => 'StatusEnum', // unit enum (not backed) -> also unsupported
],

// after
'attributeTypes' => [
    'count' => AttributeTypecastBehavior::TYPE_INTEGER,
    'active' => AttributeTypecastBehavior::TYPE_BOOLEAN,
    'status' => StatusEnum::class, // enum Status: int { ... } (backed, PHP 8.1+)
],
Defensive patterns

Strategy: validation

Validate before calling

$allowed = ['integer', 'float', 'boolean', 'string'];
$isEnumType = PHP_VERSION_ID >= 80100 && is_string($type) && is_subclass_of($type, \BackedEnum::class);
if (!in_array($type, $allowed, true) && !$isEnumType && !is_callable($type)) {
    throw new \InvalidArgumentException("Unsupported typecast type '{$type}'");
}

Type guard

function isValidTypecastType($type): bool
{
    return is_callable($type)
        || in_array($type, ['integer', 'float', 'boolean', 'string'], true)
        || (PHP_VERSION_ID >= 80100 && is_string($type) && is_subclass_of($type, \BackedEnum::class));
}

Prevention

When it happens

Trigger: Configuring attributeTypes with shorthand names like 'int', 'bool', 'double' (only 'float' is accepted, 'double' is not in the switch) or custom labels like 'timestamp'; using a class-string of a unit enum or a non-backed enum on PHP 8.1+; referencing an enum FQCN while running PHP < 8.1 where the enum branch is compiled out; a typo in the type constant.

Common situations: Copy-pasting type names from Doctrine/PHPDoc annotations ('int', 'bool') into attributeTypes; upgrading to enum-based casting with enums that are not backed; environments differing in PHP version so the enum path silently disappears; mixing callable types (fine) with invented string type names (throws).

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/529d005998bfde90. Report an issue: GitHub.