A client that lost an answer could not ask again safely: a second submission was a second job, counted against its limits. And the three MCP tools that run declared idempotentHint: true, which was not so. POST /v1/jobs and POST /v1/run take an Idempotency-Key, and the three tools an idempotency_key. Sent again with the same key and request, a job is answered with the key's job, before any limit, counting as no submission; with another request the key is refused (J034), naming no job. A key names its job while the job is kept, but for a job the service interrupted, which the key runs again. Records keep the key's digest with the client's name; one lock makes concurrent sends of one key one job. The tools' hint is now false: a call without a key is a new job. Calls without a key are not matched by their request, since a client is an address and that would give one person's job id to anyone at the address sending the same program. The command line and the Python client send each job under a fresh key, and send it again under it where no answer came back, only to a service that says it keeps keys. The Python client's wait also ends on an interrupted job, where it ran to its deadline before. Co-Authored-By: Claude Opus 5.5 <[email protected]>
11 KiB
Job refusals: codes
The reader gives every refusal and warning about a program's text a code
(Q…, qasm-diagnostics.md). What is asked of a
program has codes of its own (J…): the request, the method, an intent, a
repair, and the host that runs the job. A refusal reads, on every surface:
stabilizer needs a Clifford circuit: … [J011]
A refusal whose cause is a reader's code keeps that code before its own:
exact: exact needs dyadic angles: the angle 0.3 is not a dyadic multiple of 2π (2πm/2^k, k ≤ 32) [Q500] [J011]
As data (the verdict's refusal, an MCP tool's error), a refusal carries its
message, its code (the last it gives), every code it gives in order
(codes), the code's outcome and its meaning. A failure that no code
names (an internal error) has code null and the outcome failed.
Stability. A code never changes meaning once released. New codes are only ever added; a retired code keeps its row, so a code in an old log or receipt still means what it meant then.
Outcomes.
refused: the job does not run as asked. Change it, as the message says, or run it elsewhere.retry: the host did not take the job now. The same job may be sent again later.
An answer's view statements (the answer view layer,
quantum-answers.md) have codes of their
own, J100 to J112, each saying what becomes of the statement:
dropped: the statement is left out, and the rest of the answer is drawn. An answer's errors, the ones a model is sent back, are its dropped codes.defaulted: the statement is read as the default the code names.warned: the statement is drawn as written, with a note that is not sent back to the model.
A program in an answer is read by the reader, so its refusals and warnings keep
the reader's codes (Q…).
The table is also served as data: wai_quantum::engine::refusal::codes() in
Rust, wai-quantum diagnostics [--json] on the command line (beside the
reader's codes, under job_codes), the qasm_diagnostics tool of both MCP
servers (code takes either kind), and engine_diagnostic_codes() in the
browser engine. A test holds this page to the code's table.
| Code | Outcome | Meaning |
|---|---|---|
J001 |
refused | A request that is not a job: not a JSON object, or no qasm program in it. |
J002 |
refused | A job that names a provider, sent to a host that reaches none: it runs where the person's credentials are (the command line's run --provider, its MCP server's run_on_provider, or the desktop app). |
J003 |
refused | A field of the job that does not read: an observable, an amplitude's bit string, the noise or the method's options (the message names the field and what it takes). |
J004 |
refused | A job that asks for nothing: give shots, observables or amplitudes. |
J005 |
refused | More than one job may ask: shots, observables or amplitudes past their limits, or a whole number past ±(2^53 − 1), which JSON readers would not all read alike. |
J006 |
refused | The compile the job asked for did not complete, or its options do not read (the message says why). |
J007 |
refused | A set that does not read, or a set sent where one job is read: programs not a list of programs or jobs, a sweep whose names are not the program's inputs or whose values are not lists of numbers, both given, or more items than a set holds. |
J008 |
refused | The mitigation the job asked for does not read or cannot be done: no noise model, no observables (no shots, for readout), a program that measures in the middle, more qubits or work than it takes, a device target beside it, or options that do not read (the message says which). |
J009 |
refused | An error-correction request that does not read or cannot be done: an unknown code or decoder, a decoder the code does not admit, a syndrome or an error that does not fit the code, circuit text or a model that does not read, or sizes past the limits (the message says which). |
J010 |
refused | A method that does not exist: the methods list names them. |
J011 |
refused | The method named cannot take this job: a gate it does not hold, more qubits, memory or work than it takes here, or an answer it does not give (noise it cannot take is J061); the message says which, and auto picks a method that can. |
J012 |
refused | No method takes this job: each method's reason is listed, so the job can be changed to suit one. |
J013 |
refused | A placement on the fabric (fabric) this host cannot honour: no member by that name, no certified accelerator member here, a state or a partition larger than a member holds, a partition count that is not a power of two, or a method or program the fabric's members do not run (the message says which, and what is here). |
J020 |
refused | An intent that does not read: not one of distribution, equivalent or prepares, a distribution whose outcomes are not the program's bits or whose probabilities do not sum to 1, or a reference program that does not read. |
J021 |
refused | A proposed repair that changes a line no diagnostic flags, or adds lines away from one: rejected, and the program left as it was. |
J022 |
refused | A repair's choices that do not read (max_iterations, dyadic_bits, sizes), or a proposal that is not a program's text. |
J030 |
retry | The host takes no more from this client for now (submissions in a window, or jobs at once): send it again shortly. |
J031 |
refused | A job or a check larger than this host takes: run it on your own machine, with the command line or its MCP server. |
J032 |
retry | The host is full (its queue, or the checks running at once): send it again later. |
J033 |
refused | A host that takes requests only with one of its API keys: give yours as Authorization: Bearer <key>; a key it does not hold is refused the same way. |
J034 |
refused | An idempotency key (Idempotency-Key, or a tool's idempotency_key) that does not read, or that this client sent before with another request: a key names one job, so another request needs another key. A key is 1 to 255 visible ASCII characters, and should be unguessable (a UUID, or 128 random bits). |
J040 |
refused | A pulse run that does not read or cannot be done: a field it does not take, options or device parameters that do not read, a target without the qubit, or a schedule outside the simulator's model (two tones on one qubit at once, a play after its qubit's capture, more levels and qubits than it holds, a frame far from its qubit); the message says which. |
J041 |
refused | A pulse run whose integration error cannot be stated within its tolerance: a step longer than the generator's norm allows, or a schedule so long that the bound or the rounding passes the tolerance; the message names the steps that would meet it, or says that none does. |
J050 |
refused | A job's params that do not read: not an object of finite numbers, a name the program does not declare as a parameter (input float, input angle), or a parameter of the program left without a value. |
J051 |
refused | A gradient that cannot be taken: a differentiation method that does not exist, a parameter the reader cannot carry to the gates (its cause Q129), a program that measures in the middle, noise, no Hamiltonian, or more qubits or work than it takes (the message says which). |
J052 |
refused | An optimisation, a variational eigensolver or a QAOA run that does not read or cannot be done: an unknown optimiser, settings or steps past their limits, a Hamiltonian or a graph that does not read (the message says which). |
J053 |
refused | An algorithm builder's request that does not read: an unknown algorithm, sizes past its limits, or arguments it does not take (the message says which). |
J060 |
refused | A compiler pass a request names (compile.passes) that this host does not hold: the components list names every method, pass, noise channel and front end here, and no host loads a component from a request. |
J061 |
refused | A noise channel the method cannot take: a method that models no noise, or a channel the method has no form for (amplitude damping on the stabilizer's Pauli frames, a registered channel on a method that takes only the built-in ones); the message names what does take it. |
J062 |
refused | A noise channel whose parameters do not read or whose operators fail its validity check: a value outside its range, Kraus operators that are not completely positive and trace preserving (their sum of K†K off the identity), or a Pauli form whose probabilities are negative, do not sum to 1, or are not the channel its operators make (the message says by how much). |
J063 |
refused | A component the registry does not take: a name its kind holds already (a built-in's among them), a name or version that is empty or not plain text, a descriptor that is not a JSON object, a channel on other than one or two qubits, or a pass whose check states no bound. |
J064 |
refused | A registered component's answer that breaks the engine's contract: a method's result without an accuracy class it declared, or one that writes a member the engine writes (method, qubits, gates, compiled, repaired, engine, schema, components, receipt, verdict); a pass's gates on qubits the program does not have, or that do not read back; a front end's program that does not read. Nothing it gave is returned. |
J065 |
refused | An intent on a job whose noise names a registered channel: the intent checks model the built-in channels alone, so the check is refused rather than made against another model. |
J100 |
dropped | A line of an answer that is not a statement (name = View(...)), a program (a fenced qasm block with its name), a comment or a marker: left out. |
J101 |
dropped | A view the answer layer does not have: left out (the views are listed in the layer's specification). |
J102 |
dropped | An @ call the engine does not have: the statement is left out. |
J103 |
dropped | A view or an @ call without an argument it requires: the statement is left out. |
J104 |
dropped | An argument of the wrong kind, such as a number where a view takes the engine's call (a number in a view comes from the engine), or a program where a list is taken: the statement is left out. |
J105 |
warned | More arguments than a view or an @ call takes: the extra ones are left out. |
J106 |
dropped | A name no statement declares, or one whose statement was left out (a program the reader refused, say): the statement that names it is left out. |
J107 |
defaulted | No root = Answer([...]): the views are drawn in the order they are written. |
J108 |
dropped | The answer ends inside a program or a statement: the unfinished part is left out. |
J109 |
dropped | Statements that name each other in a cycle: each is left out. |
J110 |
warned | A name declared again: the later declaration stands, which is how an answer is edited. |
J111 |
warned | A number written in a view's text, which no engine call gave: let a view show it. |
J112 |
warned | A statement the root does not reach: it is not drawn. |