thedotmack/claude-mem · warning
Conflict
Conflict
Error message
Generation job is currently processing; cancel or wait for completion before retrying
What it means
POST /v1/jobs/:id/retry answers 409 when the job's current status is 'processing'. An in-flight worker must be allowed to finish or fail through its normal lifecycle, so re-enqueueing is refused; the operator can wait for completion or cancel first. This is a state-machine guard, not an error in the request itself.
Source
Thrown at src/server/routes/v1/ServerV1PostgresRoutes.ts:1463
load: (projectId) => repo.getByIdForScope({ id, projectId, teamId }),
});
if (!current) return null;
// Idempotent fast-path: already queued -> emit audit only, no DB writes.
if (current.status === 'queued') {
await this.auditWrite(req, 'generation_job.retried_by_operator', current.id, current.projectId, {
outcome: 'noop_already_queued',
currentAttempts: current.attempts,
requestId: req.requestId ?? null,
});
return { job: current, retriedCount: extractRetriedCount(current.payload), alreadyQueued: true };
}
if (current.status === 'processing') {
// Refuse retry on in-flight jobs — the running worker MUST be allowed
// to finish or fail through its normal lifecycle. Operator can wait
// or cancel, then retry.
res.status(409).json({
error: 'Conflict',
message: 'Generation job is currently processing; cancel or wait for completion before retrying',
});
return null;
}
if (current.status === 'completed') {
// Refuse retry on already-completed jobs. The deduplication index on
// observations (generation_key = job_id + index + content) does NOT
// protect against re-running the provider, because LLM output is
// non-deterministic and the second run almost always produces a
// different content string. Replaying would persist a parallel set
// of observations attributed to the same generation_job_id.
// cancelGenerationJob applies the same 409 guard for the same reason.
res.status(409).json({
error: 'Conflict',
message: 'Generation job already completed; retrying would duplicate observations',
});View on GitHub (pinned to e2d1df569a)
Solutions
- GET /v1/jobs/:id and check status is not 'processing' before retrying
- Wait for the worker to settle, or POST /v1/jobs/:id/cancel and then retry
- Disable the retry action in UI/automation while status is 'processing'
Defensive patterns
Strategy: validation
Validate before calling
// Check status before retrying
const res = await fetch(`${base}/v1/jobs/${jobId}`, { headers });
const { generationJob } = await res.json();
if (generationJob.status === 'processing') {
// wait, or cancel first — do not retry
return { deferred: true };
}
await fetch(`${base}/v1/jobs/${jobId}/retry`, { method: 'POST', headers }); Type guard
type RetryableStatus = 'failed' | 'cancelled'; const isRetryable = (status: string): status is RetryableStatus => status === 'failed' || status === 'cancelled';
Try / catch
Treat 409 'currently processing' as a signal to back off: re-check status on a timer and retry only once the job leaves 'processing'; never blind-retry the POST.
Prevention
- Always render job status next to the retry action and gate the action on it
- Debounce retry buttons to kill double-clicks
- In automation, poll GET /v1/jobs/:id to terminal status before deciding to retry
When it happens
Trigger: Calling retry while the generation worker holds the job — e.g. right after a failed attempt bounced it back to queued and it was picked up again, or while a dashboard shows status 'processing'.
Common situations: Retry buttons that don't refresh job status first; automation polling faster than the worker lifecycle; double-clicking retry.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- observation generation job status transition was not applied
- Chroma query failed - connection lost: ${errorMessage}
- sync hub push ${res.status}: ${body}
- sync hub pull ${res.status}: ${body}
- Corpus "${corpus.name}" has no session — call prime first
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/563aa2d43a0b71fe.
Report an issue: GitHub.