Commit a08add5
A flow run can execute a model from a different provider than the node selects,
and neither the database nor the widget predicts it. This lands the evidence,
the ledger row and the warning for the next reader. It changes no test, on
purpose — see the last section.
## What was established
`POST /api/v2/workflows` carries a `data` field that `WorkflowRunRequest`
declares as an "Optional live-canvas override of the flow's nodes/edges; takes
priority over the saved flow data", and a capture of a HEALTHY Playground run
confirms the frontend always sends it. So the backend builds the canvas, not the
row, and `GET /api/v1/flows/{id}` is not a weak observable for the executed
model — it is the wrong object.
The runtime does not substitute either: `get_llm` raises "A model selection is
required" on an empty list and "The selected model is missing a provider" on a
blank provider. What substitutes is the editor build config, where an EMPTY
`ModelInput` value is filled with `options[0]` — and `options` is a FLAT list
across every enabled provider, so the fill need not be the node's own provider.
Measured through `POST /api/v1/custom_component/update` on 1.12.0.dev19, an
OpenAI-Compatible node with an empty value came back `claude-opus-5` /
Anthropic.
It fails loudly in `openai-compatible-provider-setup.spec.ts` only because that
provider's endpoint-derived default set starts with completions-only ids
(`404 ... This is not a chat model`). On 6 of the 8 providers measured,
`options[0]` is a working chat model, so the same substitution produces a
PASSING run against a model nobody selected, on a provider nobody selected,
billed to that provider's account.
## What was refuted, and why that is the load-bearing half
Two backend explanations were tested and both died, which is what narrows the
trigger to editor state and saves upstream the same investigation:
- an INVALID selection is not reset — a deliberately impossible model
(`definitely-not-a-model` / `Nope`) is preserved, so the `[options[0]]` branch
does not fire for out-of-catalog values;
- an empty `options` list does not wipe a real selection — with every provider
credential deleted, `options` comes back as 1, not 0, because the selection is
injected into the options.
What EMPTIES the field on a node that had a selection is still unknown, and the
report says so rather than implying a complete chain.
## Honesty about the rate
The pre-fix baseline over 12 runs of the untouched spec reproduced the symptom
ZERO times. The runner reported "3/12 failed (25%)", but two of those carry
`unexpected=0` — no test failed, they were counted because a backend error was
logged — and the single genuine failure carries `TimeoutError:
page.waitForResponse: Timeout 60000ms exceeded`, a different symptom. The
finding rests on the deterministic experiment, not on frequency.
## Why no spec changed
Strengthening the existing persisted-binding assertion would be engineering a
spec to pass against an observable that structurally cannot see the defect. A
re-selection repair loop was already written, measured against two real
occurrences and removed for exactly that reason (#1369). The spec doc now states
that the pre-send re-read is attribution and must NOT grow into a gate, so the
next reader does not spend a cycle re-strengthening the wrong object; a guard
that genuinely covers this belongs on the run request and is tracked separately.
Refs #1372 — deliberately NOT "Closes": the issue stays open per its own
deliverable, pending the trigger and the upstream fix landing in the nightly.
Co-authored-by: Rafael <rafael@oriontech.me>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent e0ed7a5 commit a08add5
3 files changed
Lines changed: 197 additions & 3 deletions
File tree
- docs
- core-functionality/model-provider
- upstream-bugs
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | | - | |
| 43 | + | |
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| |||
Lines changed: 32 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
167 | 199 | | |
168 | 200 | | |
169 | 201 | | |
| |||
Lines changed: 161 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
0 commit comments