#20513·filament

QueryBuilder indicators throw "No query builder block found" when an applied rule is removed in the deferred filters form

Author: MaartenJCCreated Sep 16, 2026Updated Sep 17, 2026
Labelsbugunconfirmedmedium priority

Package

filament/tables

Package Version

v5.8.2 (also v5.8.1)

Laravel Version

v13.32.0

Livewire Version

v4.4.5

PHP Version

PHP 8.4.23

Problem description

With deferred filters (the default), a QueryBuilder filter throws a LogicException during a full render when a rule is applied but has since been deleted from the filters form without applying again:

No query builder block found for [price]. (View: vendor/filament/tables/resources/views/index.blade.php)
at vendor/filament/tables/src/Filters/QueryBuilder.php:100

QueryBuilder::getRuleSummaries() (called from indicateUsing()) receives the rules from the applied state (tableFilters, via getTableFilterState()), but looks each rule up with $ruleBuilder->getChildSchema($ruleIndex). The RuleBuilder lives in the filters form, whose state path is tableDeferredFilters, so its child schemas are built from the deferred state. When the two differ structurally (rule deleted in the form, not applied yet), the lookup returns null and the exception is thrown.

applyFiltersToTableQuery() already handles this mismatch by temporarily switching the form state path to tableFilters; building the indicators does not.

It only surfaces on a full render. The builder's delete action renders partially, so clicking delete on its own is fine. But when the same request also carries a pending deferred wire:model update (e.g. the user changed another field in the filters form first), PartialsComponentHook falls back to a full render, the table view calls getFilterIndicators(), and the request crashes. In production the logged Livewire method was callMountedAction.

Expected behavior

The table keeps rendering. The indicators should be built from the applied state with a rule builder that matches that state (or rules without a matching block should be skipped) instead of throwing.

Steps to reproduce

  1. A resource table with deferred filters, a SelectFilter and a QueryBuilder:
php
->filters([
    SelectFilter::make('status')
        ->options([
            'active' => 'Active',
            'archived' => 'Archived',
        ]),
    QueryBuilder::make('extra')
        ->constraints([
            NumberConstraint::make('price'),
        ]),
])
  1. Open the filters, add a rule "Price is minimum 10" and apply.
  2. Open the filters again, change the Status select (don't apply), then click delete on the price rule.
  3. The request fails with No query builder block found for [price].

The reproduction repository contains a failing test for this (tests/Feature/QueryBuilderIndicatorsTest.php):

php
$rule = ['type' => 'price', 'data' => ['operator' => 'isMin', 'settings' => ['number' => 10]]];

$component = Livewire::test(ListProducts::class)
    ->set('tableDeferredFilters.extra.rules', ['rule-uuid' => $rule])
    ->call('applyTableFilters')
    ->mountAction(TestAction::make('delete')
        ->schemaComponent('extra.rules', schema: 'tableFiltersForm')
        ->arguments(['item' => 'rule-uuid']));

// A pending deferred update in the same request forces a full render, as in the browser
$component->update(
    calls: [['method' => 'callMountedAction', 'params' => [], 'path' => '']],
    updates: ['tableDeferredFilters.status.value' => 'archived'],
);

Workaround we use for now, a subclass that skips rules the builder doesn't know:

php
public function getRuleSummaries(array $rules, RuleBuilder $ruleBuilder, int $iteration = 1): array
{
    $knownRules = array_filter(
        $rules,
        fn (mixed $rule, int|string $ruleIndex): bool => $ruleBuilder->getChildSchema($ruleIndex) !== null,
        ARRAY_FILTER_USE_BOTH,
    );

    return parent::getRuleSummaries($knownRules, $ruleBuilder, $iteration);
}

Reproduction repository (issue will be closed if this is not valid)

https://github.com/MaartenJC/filament-querybuilder-repro

Run php artisan test --filter=QueryBuilderIndicatorsTest.

Relevant log output

Illuminate\View\ViewException: No query builder block found for [price]. (View: vendor/filament/tables/resources/views/index.blade.php) (View: vendor/filament/tables/resources/views/index.blade.php)
at vendor/filament/tables/src/Filters/QueryBuilder.php:100