filamentphp/filament · error · LogicException

You cannot use the `enableToolbarButtons()` method when the

Error message

You cannot use the `enableToolbarButtons()` method when the toolbar buttons are dynamically returned from a function. Instead, return the enabled buttons from the function.

What it means

The mirror of `disableToolbarButtons()`: `enableToolbarButtons()` re-enables buttons against a statically configured toolbar list, which is meaningless when the list is produced by a Closure. Filament detects `toolbarButtons instanceof Closure` and throws a LogicException at configuration time, telling you to return the enabled buttons from the function instead.

Source

Thrown at packages/forms/src/Components/Concerns/InteractsWithToolbarButtons.php:53

        if ($this->toolbarButtons instanceof Closure) {
            throw new LogicException('You cannot use the `disableToolbarButtons()` method when the toolbar buttons are dynamically returned from a function. Instead, do not return the disabled buttons from the function.');
        }

        $this->toolbarButtonsModifications[] = [
            'type' => 'disable',
            'buttons' => $buttonsToDisable,
        ];

        return $this;
    }

    /**
     * @param  array<string | object | array<string | object>>  $buttonsToEnable
     */
    public function enableToolbarButtons(array $buttonsToEnable = []): static
    {
        if ($this->toolbarButtons instanceof Closure) {
            throw new LogicException('You cannot use the `enableToolbarButtons()` method when the toolbar buttons are dynamically returned from a function. Instead, return the enabled buttons from the function.');
        }

        $this->toolbarButtonsModifications[] = [
            'type' => 'enable',
            'buttons' => $buttonsToEnable,
        ];

        return $this;
    }

    /**
     * @param  array<int, string | object | array<int, string | object>> | Closure | null  $buttons
     */
    public function toolbarButtons(array | Closure | null $buttons): static
    {
        $this->toolbarButtons = $buttons;
        $this->toolbarButtonsModifications = [];

View on GitHub (pinned to 53483fa934)

Solutions

  1. Include the extra buttons in the Closure's return value.
  2. If runtime enable/disable is required, use the static form `->toolbarButtons([...])`.
  3. Push role logic into the Closure instead of stacking modification methods on top of it.

Example fix

// before
RichEditor::make('content')
    ->toolbarButtons(fn (): array => ['bold', 'italic'])
    ->enableToolbarButtons(['codeBlock']),

// after
RichEditor::make('content')
    ->toolbarButtons(fn (): array => ['bold', 'italic', 'codeBlock']),
Defensive patterns

Strategy: validation

Validate before calling

// Decide one strategy up front in shared field builders
$field = RichEditor::make('content');

if ($roleToolbarsEnabled) {
    $field->toolbarButtons(fn (): array => ['bold', 'italic', 'codeBlock']); // include enabled set
} else {
    $field->toolbarButtons(['bold', 'italic'])
        ->enableToolbarButtons(['codeBlock']);
}

Type guard

function usesDynamicToolbar(RichEditor $field): bool
{
    $reflection = new ReflectionProperty(RichEditor::class, 'toolbarButtons');
    $reflection->setAccessible(true);

    return $reflection->getValue($field) instanceof Closure;
}

Prevention

When it happens

Trigger: Chaining `->enableToolbarButtons(['codeBlock'])` onto a `RichEditor` configured with `->toolbarButtons(fn () => [...])`.

Common situations: Upgrading code that enabled extra buttons after the fact, then moving the toolbar config into a Closure for role-based toolbars without removing the enable call.

Related errors


AI-assisted analysis of filamentphp/filament@53483fa934 (2026-08-17). Data as JSON: /api/errors/42b45413be4ab7f4. Report an issue: GitHub.