swarm-controller: 409 instead of 400 for a terminal-state rejection

This commit is contained in:
damocles 2026-09-07 20:15:27 +02:00 committed by mara
commit ded23b711f

View file

@ -794,7 +794,8 @@ fn declaration_target(
request_body = SetAgentStateRequest,
responses(
(status = 200, description = "the declaration as now published", body = Vec<AgentDeclaration>),
(status = 400, description = "a name is not an identifier, the hive is not in this swarm, the state is unknown, or the agent is already declared destroyed (terminal — problem+json)", body = String),
(status = 400, description = "a name is not an identifier, the hive is not in this swarm, or the state is unknown (problem+json)", body = String),
(status = 409, description = "the agent is already declared destroyed, a terminal state the request tries to move it off of (problem+json)", body = String),
(status = 503, description = "no swarm queue is wired up (problem+json)", body = String),
(status = 500, description = "the declaration could not be published (problem+json)", body = String),
),
@ -812,11 +813,13 @@ async fn set_agent_state(
.into_string();
let declaration = writer.set(&hive, &agent, req.state).await.map_err(|e| {
// A `TerminalStateError` is the caller's mistake (asking to move an
// agent off a state its own doc comment says is terminal), not a
// server fault — everything else here is the pre-existing catch-all.
// A `TerminalStateError` is the caller's mistake, but not a malformed
// request — the request is well-formed, it just conflicts with the
// target resource's current (terminal) state, which per RFC 9110 is
// what 409 exists for, not 400. Everything else here is the
// pre-existing catch-all.
if let Some(terminal) = e.downcast_ref::<wanted::TerminalStateError>() {
return error_problem(axum::http::StatusCode::BAD_REQUEST, &terminal.to_string());
return error_problem(axum::http::StatusCode::CONFLICT, &terminal.to_string());
}
tracing::warn!(hive = %hive, agent = %agent, error = %format!("{e:#}"), "declaring agent state failed");
error_problem(