Opening this rather than adding a fourth change to a subsystem that took five merges today, two of which fix the same leak twice.
Bisected: #2774 is the window
integriq's flow-native-sync.spec.ts:876 is deterministically red on development (two runs + a Playwright retry). By job timestamps:
|
|
| passed (integriq#1526) |
07:48–08:07 UTC |
| failed (development) |
08:46–09:05 UTC |
The only behavioural change in openregister development inside that window is #2774 — "make {register} a hard boundary on every path that names one", the commit that introduced RegisterScopedSchemaResolver.
Not caused by #2790: that merged 10:57 UTC, ~2h after the first failure.
Symptom 1 — a schema-only lookup inherits an unrelated register (CI)
object-write fails mid-flow:
Schema slug "synchronization_contract" is not carried by register
"fns-mt4du8ca-62fj-reg" (id 15), which carries 2 schema(s).
1 schema(s) elsewhere on this instance carry this slug
synchronization_contract lives in the openconnector register. The register named in the error is the test's own register, created by the spec with 2 schemas. Every openconnector call site I checked (SynchronizationContractService, SynchronizationService:999/1459/1494/1542, SynchronizationContractProvider) names register: 'openconnector' explicitly — so this is a lookup picking up a sticky register it never named.
Symptom 2 — the same shape, different slug (dev instance)
Every openconnector object read failed with Schema slug "application" is not carried by register "openconnector" while the caller had asked for synchronization. Diagnosed as the pending schema ref leaking across callers; fixed in #2790, and #2792 independently fixed the same mechanism 12 minutes later. Two fixes, one bug — worth reconciling.
Symptom 3 — the objects API cannot resolve ANY register (dev instance)
Reproducible with plain curl, by slug and by id, while the registers API resolves the same register fine:
GET /api/registers/65 -> 200, register 65 "openconnector"
GET /api/objects/openconnector/synchronization -> {"message":"Register not found: 'openconnector'"}
GET /api/objects/65/synchronization -> {"message":"Register not found: '65'"}
The e2e hits this too: a register it has just created comes back Register not found: '4895'.
Why this was invisible for hours
FlowEngine logs a throwing step as status: 'failed' with the message in that entry's error, then returns a run whose status is stopped and whose run-level error is null. Since stopped counts as successful, a run that died mid-pipeline satisfied "terminal", "successful" and "no error" simultaneously. Only a separate step-list assertion noticed, and it reported a missing-steps diff — which reads like a routing bug and sent me a full CI round in the wrong direction.
Fixed on the integriq side (assert no step has status: failed, and interpolate the engine's message, since the run object carries it nowhere else). Worth considering whether the run-level error should be populated when a step fails — right now the API's own summary of a failed run says nothing failed.
Opening this rather than adding a fourth change to a subsystem that took five merges today, two of which fix the same leak twice.
Bisected: #2774 is the window
integriq'sflow-native-sync.spec.ts:876is deterministically red on development (two runs + a Playwright retry). By job timestamps:The only behavioural change in openregister development inside that window is #2774 — "make {register} a hard boundary on every path that names one", the commit that introduced
RegisterScopedSchemaResolver.Not caused by #2790: that merged 10:57 UTC, ~2h after the first failure.
Symptom 1 — a schema-only lookup inherits an unrelated register (CI)
object-writefails mid-flow:synchronization_contractlives in the openconnector register. The register named in the error is the test's own register, created by the spec with 2 schemas. Every openconnector call site I checked (SynchronizationContractService,SynchronizationService:999/1459/1494/1542,SynchronizationContractProvider) namesregister: 'openconnector'explicitly — so this is a lookup picking up a sticky register it never named.Symptom 2 — the same shape, different slug (dev instance)
Every openconnector object read failed with
Schema slug "application" is not carried by register "openconnector"while the caller had asked forsynchronization. Diagnosed as the pending schema ref leaking across callers; fixed in #2790, and #2792 independently fixed the same mechanism 12 minutes later. Two fixes, one bug — worth reconciling.Symptom 3 — the objects API cannot resolve ANY register (dev instance)
Reproducible with plain curl, by slug and by id, while the registers API resolves the same register fine:
The e2e hits this too: a register it has just created comes back
Register not found: '4895'.Why this was invisible for hours
FlowEnginelogs a throwing step asstatus: 'failed'with the message in that entry'serror, then returns a run whose status isstoppedand whose run-levelerroris null. Sincestoppedcounts as successful, a run that died mid-pipeline satisfied "terminal", "successful" and "no error" simultaneously. Only a separate step-list assertion noticed, and it reported a missing-steps diff — which reads like a routing bug and sent me a full CI round in the wrong direction.Fixed on the integriq side (assert no step has
status: failed, and interpolate the engine's message, since the run object carries it nowhere else). Worth considering whether the run-levelerrorshould be populated when a step fails — right now the API's own summary of a failed run says nothing failed.