Found while working #1334. Same dead premise, a second copy — not currently red, because the spec never runs anywhere that would tell us.
What it is
tests/tests-automations/regression/mcp/client/mcp-client-agent.spec.ts:86 carries its own local copy of the #751 credential-settle guard:
// #751: the model selection rebinds `api_key` via a debounced autosave — running the
// Playground before it lands builds with the wrong provider's key.
async function waitForAgentCredentialSettled(page, flowId, expectedCredential) {
...
expect(agent?.data?.node?.template?.api_key?.value).toBe(expectedCredential);
}).toPass({ timeout: 20000, intervals: [500, 1000, 2000] });
}
Upstream #14311 ("stop automatic provider field binding", on the 1.12 line since 2026-08-04) deleted the block that wrote the credential variable name into api_key. Measured on 1.12.0.dev18/dev19 while working #1334: the field reads {value: "", load_from_db: false} on every build, from mount onward, for the OpenAI Compatible provider and for the plain OpenAI provider — build-wide, not provider-specific. So the transition this guard waits for cannot happen; it can only burn its 20 s and fail.
Why the earlier sweeps missed it
#1274 migrated the shared helper tests/helpers/flows/agent-credential-settle.ts off this axis and 19 @stable specs came with it. #1334 migrated the remaining inline copy in openai-compatible-provider-setup.spec.ts, and its grep — for credential: — reported that as the last one. This copy spells the same read api_key?.value, so that grep could not see it. It is the third instance of the same premise and the first that no sweep has touched.
Why it is not red today, which is the actual problem
The spec is tagged @mcp @agents @regression — no @stable — so daily-stable.yml never runs it, and pr-validation.yml only selects it for a PR that touches its import graph. It is latently broken: whoever runs it next, or whoever promotes it, pays. That is the #945/#940 shape — a spec with no @stable is an invisible red — and it is why this is worth an issue rather than a note.
The fix is already written twice
agent-credential-settle.ts (#1274) is the reference: the credential is no longer stored but is still determined, by the provider of the selected model, so the guard settles on model.value[0].provider instead. #1334 proved that causally on the run path — instantiation.py reads that field and calls get_api_key_for_provider, which with an empty api_key resolves get_provider_secret_variable_key(provider); dropping only the provider's own credential turns the run into 401 Incorrect API key provided: EMPTY while the binding is unchanged.
Note the local guard also predates the shared helper — the first question is whether it should be replaced by agent-credential-settle.ts outright rather than re-pointed in place, which would delete the divergence instead of updating it.
Deliverables (Done when)
Found while working #1334. Same dead premise, a second copy — not currently red, because the spec never runs anywhere that would tell us.
What it is
tests/tests-automations/regression/mcp/client/mcp-client-agent.spec.ts:86carries its own local copy of the #751 credential-settle guard:Upstream #14311 ("stop automatic provider field binding", on the 1.12 line since 2026-08-04) deleted the block that wrote the credential variable name into
api_key. Measured on1.12.0.dev18/dev19while working #1334: the field reads{value: "", load_from_db: false}on every build, from mount onward, for the OpenAI Compatible provider and for the plain OpenAI provider — build-wide, not provider-specific. So the transition this guard waits for cannot happen; it can only burn its 20 s and fail.Why the earlier sweeps missed it
#1274 migrated the shared helper
tests/helpers/flows/agent-credential-settle.tsoff this axis and 19@stablespecs came with it. #1334 migrated the remaining inline copy inopenai-compatible-provider-setup.spec.ts, and its grep — forcredential:— reported that as the last one. This copy spells the same readapi_key?.value, so that grep could not see it. It is the third instance of the same premise and the first that no sweep has touched.Why it is not red today, which is the actual problem
The spec is tagged
@mcp @agents @regression— no@stable— sodaily-stable.ymlnever runs it, andpr-validation.ymlonly selects it for a PR that touches its import graph. It is latently broken: whoever runs it next, or whoever promotes it, pays. That is the #945/#940 shape — a spec with no@stableis an invisible red — and it is why this is worth an issue rather than a note.The fix is already written twice
agent-credential-settle.ts(#1274) is the reference: the credential is no longer stored but is still determined, by the provider of the selected model, so the guard settles onmodel.value[0].providerinstead. #1334 proved that causally on the run path —instantiation.pyreads that field and callsget_api_key_for_provider, which with an emptyapi_keyresolvesget_provider_secret_variable_key(provider); dropping only the provider's own credential turns the run into401 Incorrect API key provided: EMPTYwhile the binding is unchanged.Note the local guard also predates the shared helper — the first question is whether it should be replaced by
agent-credential-settle.tsoutright rather than re-pointed in place, which would delete the divergence instead of updating it.Deliverables (Done when)
api_key.value, by adopting the shared helper or by re-pointing onto the provider axis with the same verdict taxonomy.--retries=0runs) — it has no@stable, so "it compiles" is not evidence.api_key) and not one spelling of it.@stable, or state why not — a spec nothing runs cannot report a regression.