yiisoft/yii2 · error · yii\base\InvalidArgumentException

Attribute name must contain word characters only.

Error message

Attribute name must contain word characters only.

What it means

BaseHtml::getAttributeName() strips the tabular prefix/suffix from an attribute expression using Html::$attributeRegex ('/(^|.*\])([\w\.\+]+)(\[.*|$)/u'); if the expression does not match — i.e. the attribute part contains characters outside word chars, dot, or plus — it throws InvalidArgumentException. Every active* form helper resolves attribute names through this method, so malformed attribute expressions break form rendering.

Source

Thrown at framework/helpers/BaseHtml.php:2274

     *
     * - `[0]content` is used in tabular data input to represent the "content" attribute
     *   for the first model in tabular input;
     * - `dates[0]` represents the first array element of the "dates" attribute;
     * - `[0]dates[0]` represents the first array element of the "dates" attribute
     *   for the first model in tabular input.
     *
     * If `$attribute` has neither prefix nor suffix, it will be returned back without change.
     * @param string $attribute the attribute name or expression
     * @return string the attribute name without prefix and suffix.
     * @throws InvalidArgumentException if the attribute name contains non-word characters.
     */
    public static function getAttributeName($attribute)
    {
        if (preg_match(static::$attributeRegex, $attribute, $matches)) {
            return $matches[2];
        }

        throw new InvalidArgumentException('Attribute name must contain word characters only.');
    }

    /**
     * Returns the value of the specified attribute name or expression.
     *
     * For an attribute expression like `[0]dates[0]`, this method will return the value of `$model->dates[0]`.
     * See [[getAttributeName()]] for more details about attribute expression.
     *
     * If an attribute value is an instance of [[ActiveRecordInterface]] or an array of such instances,
     * the primary value(s) of the AR instance(s) will be returned instead.
     *
     * @param Model $model the model object
     * @param string $attribute the attribute name or expression
     * @return string|array|null the corresponding attribute value
     * @throws InvalidArgumentException if the attribute name contains non-word characters.
     */
    public static function getAttributeValue($model, $attribute)
    {

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Sanitize dynamic field names to [A-Za-z0-9_.+] before rendering (e.g. preg_replace('/[^\w\.\+]/', '_', $name)).
  2. Map external/custom field names to safe model attributes through a lookup table instead of forwarding them raw.
  3. Pre-test expressions with preg_match(Html::$attributeRegex, $name) and fall back to a safe default for failures.
  4. Keep virtual attribute names (model methods like getName0) word-char only.

Example fix

// before
echo Html::activeTextInput($model, $dynamicField); // $dynamicField = 'contact e-mail'

// after
$safeName = preg_replace('/[^\w\.\+]/u', '_', $dynamicField);
echo Html::activeTextInput($model, $safeName);
Defensive patterns

Strategy: validation

Validate before calling

if (!preg_match(\yii\helpers\Html::$attributeRegex, $attribute)) {
    throw new \InvalidArgumentException("Unsafe attribute name for form rendering: {$attribute}");
}
echo \yii\helpers\Html::activeTextInput($model, $attribute);

Type guard

/** True when Html can resolve the attribute expression. @param string $attribute */
function isRenderableAttribute(string $attribute): bool
{
    return (bool) preg_match(\yii\helpers\Html::$attributeRegex, $attribute);
}

Try / catch

try {
    $name = \yii\helpers\Html::getAttributeName($attribute);
} catch (\yii\base\InvalidArgumentException $e) {
    \Yii::warning("Rejected attribute name '{$attribute}'", 'forms');
    $name = preg_replace('/[^\\w\\.\\+]/u', '_', $attribute);
}

Prevention

When it happens

Trigger: Html::activeTextInput($model, 'full name') (space); attribute 'user-name' (hyphen); '[0]' with no attribute name after it; expressions like '[]'; an empty string; attribute names copied from DB columns containing dashes or spaces and forwarded verbatim.

Common situations: Dynamic form builders (CMS, EAV/meta fields) rendering user-defined field names; API payloads supplying field names; attributes derived from column names like 'first-name'; localization data accidentally used as attribute names.

Related errors


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