Skip to content

dev is red: the new collection-item shape guard rejects a model #308 added #345

Description

@phmatray

Problem / motivation

dev is red. CI has failed on every commit since 0ad0d49 (2026-08-13T13:17Z); 01a6580 and
everything before it was green. This blocks every open PR — each one merges a red dev and inherits
the failure.

FormCraft.ForMudBlazor.UnitTests.Fields.CollectionItemShapeGuardTests
  .No_Suite_Should_Re_Declare_A_Collection_Item_Shape_The_Fixture_Provides

  offenders should be empty but had 2 items and was
  [ FieldConfigurationRefreshTests.EqualityItemModel holds List<EqualityItem>, whose shape (String)
      is already a CollectionItemFixture item type,
    FieldConfigurationRefreshTests.EqualityItemModel is a collection root whose composition (String)
      is already modelled by CollectionItemFixture.NamedOrderModel or OrderModel ]

Reproduced on a pristine checkout of origin/dev (65944e5) with no other changes:
dotnet test FormCraft.ForMudBlazor.UnitTests/... -c ReleaseFailed: 1, Passed: 582.

Neither PR is at fault on its own

This is a semantic collision between two PRs that landed four minutes apart, each green on its own
branch:

PR What it added Merged
#308 (fix(mudblazor): re-read a field's configuration when the rendered field changes, #298) FieldConfigurationRefreshTests.EqualityItemModel / EqualityItem 947a3a5
#306 (test(mudblazor): fail the build when a suite re-declares a fixture model shape, #297) CollectionItemShapeGuardTests, which rejects exactly that shape 0ad0d49

Neither branch contained the other's code, so neither CI run could see the conflict. The guard is doing
precisely the job #297 asked for — it is the pairing that is new, not a defect in either change.

Proposed solution

The guard's own failure message names the two remedies, and choosing between them belongs to whoever
owns #298/#308, because it turns on why that suite needed its own type:

  1. Use the fixture's modelCollectionItemFixture.NamedOrderModel / OrderModel with the
    fixture's item-form builder, if the refresh test's assertions do not actually depend on
    EqualityItem's identity semantics.
  2. Allowlist it with a reason — pass FieldConfigurationRefreshTests.EqualityItemModel to
    FindOffenders' allowlist, if a local type genuinely is warranted (the test is named for equality
    behaviour, so this is plausible and is exactly the escape hatch Nothing detects a suite re-declaring a collection-item shape the fixture provides #297 built).

Deliberately not guessing here: allowlisting without cause weakens a guard that has existed for
minutes, and forcing the fixture model could silently change what the refresh test asserts.

Alternatives considered

Area

Test infrastructure — FormCraft.ForMudBlazor.UnitTests/Fields/FieldConfigurationRefreshTests.cs and
FormCraft.ForMudBlazor.UnitTests/Fields/CollectionItemShapeGuardTests.cs.

Related: #297/#306 (added the guard), #298/#308 (added the model), #205, #258, #282 (the fixture
consolidation the guard enforces), #343 (a different suite re-declaring fixture models — same class,
Fluent UI rather than MudBlazor).


Filed while merging #333, which is blocked by this: its own CI is green in isolation but fails once
dev is merged in. No implementation plan attached deliberately — the fix is a one-line judgement call
that belongs to #298/#308's author, not a multi-step task.

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:criticalMust fix immediatelystatus:triagedClassified and ready for analysis/worktype:bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions