Skip to content

RememberedApplicationAssembly (process-wide static) silently pins handler discovery for every later implicit host — order-dependent test failures with no loud signal #3521

Description

@jeremydmiller

Wolverine 6.21.0 (behavior also present in 6.20 and mirrored in JasperFx's JasperFxOptions). Not a regression — a diagnosability/documentation gap that cost a full debugging session in CritterWatch (JasperFx/CritterWatch@b365a48e has the war story).

The trap

WolverineOptions.RememberedApplicationAssembly (and JasperFx's twin) is a process-wide static: the first host that falls through to determineCallingAssembly() pins the application assembly for every later host in the process that doesn't set one explicitly. In a normal app that's one host and the cache is harmless. In a test assembly that builds many hosts (xunit/vstest process), it means:

  • whichever test class runs FIRST decides handler discovery's scanned assembly for every subsequent implicit host;
  • conventional handlers defined in the test assembly silently vanish for the whole run when an earlier host resolved to a referenced assembly instead (Tests.Common, the app-under-test's assembly, …);
  • the visible symptom is downstream and quiet — No routes can be determined for Envelope … (SomeMessage) at info level, null scatter/gather results;
  • and it's order-dependent: tests pass filtered/in isolation, fail in full-suite runs, and can flip between builds because test-order changes with recompilation. Ours initially looked exactly like a package-bump regression.

Asks (any subset)

  1. Log the pinning loudly: when establishApplicationAssembly serves RememberedApplicationAssembly to a host whose calling assembly would have resolved differently, log a warning naming both assemblies ("application assembly X reused from a previous host in this process; handler discovery will NOT scan Y — set opts.ApplicationAssembly or opts.Discovery.IncludeAssembly to override").
  2. Document the static in the testing docs (parallel/serial multi-host test processes) with the opts.Discovery.IncludeAssembly(...) / explicit opts.ApplicationAssembly remedies — the troubleshooting docs cover discovery generally but not the first-host-wins static.
  3. Consider scoping the cache (e.g., keying by calling assembly) or an opt-out for test processes.

The wolverine-troubleshooting-message-routing AI skill's IncludeAssembly guidance is what led us to the fix; the test-parallelization skill would be a natural home for a warning about this static too.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions