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.
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.