Hive Hive
Sign in

fix(server): normalize “does not contain” filter on generate runs page

GitHub issue · Closed

Metadata
Source
tuist/tuist #11200
Updated
Jun 24, 2026
Domains
Generated projects
Details

Fixes TUIST-TT

What changed

The Generations dashboard (TuistWeb.GenerateRunsLive) crashed with Flop.InvalidParamsError whenever a user applied a “does not contain” text filter (e.g. on Command or Branch). This normalizes the UI-only :"!=~" operator to :not_ilike before the filters reach Flop.

Why it crashed

The Noora filter UI exposes :"!=~" (“does not contain”) as a valid operator for text filters. Flop, however, only recognizes =~!=~ is not in its operator set. So the UI-only operator flowed straight through Filter.Operations.convert_filters_to_flop/1 into Flop.validate!/2 and raised:

Flop.InvalidParamsError: invalid Flop parameters
at Flop.validate!/2 (lib/flop.ex:1437)
at Tuist.CommandEvents.list_command_events/2 (lib/tuist/command_events.ex:25)
at TuistWeb.GenerateRunsLive.assign_generate_runs/2 (lib/tuist_web/live/generate_runs_live.ex:129)
at TuistWeb.GenerateRunsLive.handle_params/3 (lib/tuist_web/live/generate_runs_live.ex:62)

Root cause and why this fix

The sibling pages already handle this: test_runs_live.ex and gradle_build_runs_live.ex both normalize :"!=~" to Flop’s :not_ilike before building Flop filters. generate_runs_live.ex was the only one missing that normalization step. The fix mirrors the existing normalize_text_filter_operator/1 pattern from test_runs_live.ex rather than inventing a new mechanism, keeping operator handling consistent across the three pages.

User impact

Before: applying a “does not contain” filter on the Generations dashboard returned a 500 / crashed the LiveView. After: the filter works and excludes matching runs.

Validation

Written test-first (the new test reproduced the exact production stacktrace before the fix):

  • Added test/tuist_web/live/generate_runs_live_test.exs — “filters generate runs whose branch does not contain a substring” — applies filter_git_branch_op=!=~ and asserts only the non-matching run is shown.
  • mix test test/tuist_web/live/generate_runs_live_test.exs → 4 tests, 0 failures.
  • mix credo lib/tuist_web/live/generate_runs_live.ex → no issues.
  • mix format applied.

How to test locally

  1. Open a project’s module-cache/generate-runs dashboard with some generate runs.
  2. Add a text filter (Command or Branch) and set its operator to “does not contain”.
  3. Before this change the page errored; now it filters out matching runs.
Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments
TA
tuist-atlas[bot] Jun 11, 2026

The fix for the “does not contain” filter crash on the generate runs page is now available in xcresult-processor-image@0.15.0. Update to this version to prevent the Flop.InvalidParamsError when using “does not contain” text filters on the Generations dashboard.