Troubleshooting · graph
Use when
A write returned
graph_write_busy, HTTP status 503, or retry_after_seconds.Looking for something else?
A write with no reply or
outcome: unknown (problem The reply to a change was lost). A submit that ended partial (problem A submit is partly applied or unresolved).Signs
- The refusal code is
graph_write_busy, with HTTP status 503. - The refusal has
retry_after_seconds: 1and the headerRetry-After: 1. - The message reads
Graph is busy. Retry the same request with the same command key. - The
penumbracommand exits with code 5. - In
executeon the default MCP catalog, the effect has the outcomebusy, the recovery isresume_with_same_program, and the result gives aretry_aftertime.
Why it happens
Graph writes in one project take turns. Another write held the project’s write lock for too long, so your attempt could not finish in time. Penumbra rolled your attempt back and then answered busy. A direct entity change can meet this. A workspace submit can also meet it when a Shape in the project has rules, because the whole submit is then one transaction.What Penumbra does
By itself:- Answers
graph_write_busyonly after it confirmed the rollback. Nothing was applied. - Keeps the request id. The same request id with the same body is safe to send again.
- Marks the effect as busy in an
executerun, so you can resume it.
- Wait
retry_after_seconds. - Send the same request again, with the same request id and the same body.
- The CLI does not wait or retry for you after a 503.
- The SDK does not retry. Its submit call says that it never polls or retries.
Do
- Wait
retry_after_seconds. The value is 1 second. - Send the same command again with the same
--request-id. For a submit, that ispenumbra graph workspace submit "<name>" --revision <n> --request-id <key>. - In
execute, wait untilretry_after. Then resume with the same program, asrecoverysays. - If the Graph stays busy after several tries, tell the person. Keep the same request id.
Don’t
- Don’t send the request at once in a loop. The Graph needs time to free its lock.
- Don’t change the body and keep the request id. Penumbra refuses it with
idempotency_conflict. - Don’t treat busy as
unknown. A busy answer means a confirmed rollback. Anunknownoutcome needs the recovery in problem reply-lost.
Check
- The retry returns
applied, or a clear refusal. - A read of the state shows the change once.