Files
atelier/sidecar
pastilhasandClaude Opus 5 5aab279b98 the runner demanded a key the provider says it does not need
Reported against qwen-local: /providers answers `keyless: true, configured:
true, usable: true`, the POST is accepted, and the row then fails with
`No API key for provider "qwen-local"` and `duration_ms: 0` — refused at
dispatch, before inference, on a credential that cannot exist.

`queue.ts` read the key unconditionally at run time. I taught
`resolveForRequest` about keyless in the previous commit and never checked
whether anything else asked the same question. Something did.

The defect is not that one check was missed, it is that there were TWO of them.
The catalogue path and the execution path each decided independently whether a
provider was usable, from the same secret store, and disagreed the moment
"usable" stopped meaning "has a key". That is why the answer now lives on the
adapter: `adapter.keyless` is a fact about the code, so every site asks the
same question of the same source instead of re-deriving it.

The run-time read itself stays, and its reasoning is untouched: a key rotated
between queueing and running should be the new one. It just no longer applies
to a provider that has nothing to rotate. `undefined` is now the failure, not
falsiness — a keyless adapter passes an empty string deliberately.

Verified end to end, which the previous commit explicitly had not been: a
512x512 through the real queue returned `status: succeeded`, `duration_ms:
186199`, `provider: qwen-local`, and a valid 512x512 RGBA PNG on disk. The
server's own log agrees at 186.13s.

Found by the owner from the API's behaviour alone, without the source.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: de3ed4e6-f88a-429c-94e6-a760336ba83b
2026-09-21 13:21:24 +01:00
..