yiisoft/yii2 · error · yii\base\InvalidArgumentException

{class}::formName() cannot be empty for tabular inputs.

Error message

{class}::formName() cannot be empty for tabular inputs.

What it means

BaseHtml::getInputName() needs a non-empty form name to compose tabular input names like 'Post[0][title]'. If $model->formName() returns '' (as some apps override it to post bare REST fields) and the attribute expression carries a tabular prefix like '[0]title', there is no left-hand anchor for the bracket syntax, so the method throws InvalidArgumentException telling you formName() cannot be empty for tabular inputs.

Source

Thrown at framework/helpers/BaseHtml.php:2355

     * @return string the generated input name
     * @throws InvalidArgumentException if the attribute name contains non-word characters.
     */
    public static function getInputName($model, $attribute)
    {
        $formName = $model->formName();
        if (!preg_match(static::$attributeRegex, $attribute, $matches)) {
            throw new InvalidArgumentException('Attribute name must contain word characters only.');
        }
        $prefix = $matches[1];
        $attribute = $matches[2];
        $suffix = $matches[3];
        if ($formName === '' && $prefix === '') {
            return $attribute . $suffix;
        } elseif ($formName !== '') {
            return $formName . $prefix . "[$attribute]" . $suffix;
        }

        throw new InvalidArgumentException(get_class($model) . '::formName() cannot be empty for tabular inputs.');
    }

    /**
     * Converts input name to ID.
     *
     * For example, if `$name` is `Post[content]`, this method will return `post-content`.
     *
     * @param string $name the input name
     * @return string the generated input ID
     * @since 2.0.43
     */
    public static function getInputIdByName($name)
    {
        $charset = Yii::$app ? Yii::$app->charset : 'UTF-8';
        $name = mb_strtolower($name, $charset);
        return str_replace(['[]', '][', '[', ']', ' ', '.', '--'], ['', '-', '-', '', '-', '-', '-'], $name);
    }

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Make formName() return a non-empty string (the default returns the class basename) — adjust payload mapping elsewhere if bare keys are needed.
  2. For models that must keep an empty form name, render non-tabular inputs with plain attribute names (no '[i]' prefix).
  3. In API layers, map incoming bare keys to the model explicitly instead of emptying formName().
  4. If both behaviors are needed, use two model classes: one API-facing with empty formName(), one form-facing with the default.

Example fix

// before
class InvoiceItem extends \yii\base\Model
{
    public function formName() { return ''; } // breaks tabular forms
}
echo Html::activeTextInput($model, '[0]name');

// after
public function formName()
{
    return 'InvoiceItem'; // default behavior — tabular inputs work
}
echo Html::activeTextInput($model, '[0]name');
Defensive patterns

Strategy: validation

Validate before calling

$formName = $model->formName();
$isTabular = strpos($attribute, '[') === 0;
if ($isTabular && $formName === '') {
    throw new \InvalidArgumentException(get_class($model) . ' cannot render tabular inputs with an empty formName()');
}
$name = \yii\helpers\Html::getInputName($model, $attribute);

Try / catch

try {
    $name = \yii\helpers\Html::getInputName($model, '[0]' . $attr);
} catch (\yii\base\InvalidArgumentException $e) {
    // fall back to a non-tabular input for formName-less models
    $name = \yii\helpers\Html::getInputName($model, $attr);
}

Prevention

When it happens

Trigger: A model with formName() overridden to return '' used in a tabular form: Html::activeTextInput($model, '[0]name'); GridView/ListView editing multiple rows of a formName-less model; widgets that always generate tabular attribute expressions (e.g. '[]', '[1]field').

Common situations: REST-oriented models overriding formName() for cleaner payload keys, later reused in classic tabular ActiveForm rendering; API-first apps growing an admin UI; third-party widgets (multiple-input, collections) that assume a form name exists.

Related errors


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