---
title: Errors and conflicts
description: The error shape the schedule calls answer with, what each status and code means, and how to recover from a conflict.
type: how-to
product: jobs
summary: Branch on the code, retry with the same key, and re-read before you change anything after a 409
updated: 2026-09-30
order: 2
---

Every failed call on the surface that runs schedules answers with one shape.
Branch on `error.code`, log `error.message` for a person, and never parse the
message: it can name ids and revisions, and its wording is not a contract.

```json
{
  "error": { "code": "conflict", "message": "expected revision 1, current revision 2" },
  "product": "Sylphx Compute",
  "authority": "compute"
}
```

An error caused by the server is logged where operators can read it and
returned to you only as `internal`. An error body is not a debugging channel.

## Statuses

<PropertyTable
	properties={[
		{
			name: '201',
			type: 'created',
			description: 'A schedule, or a new tick, was recorded. Keep the returned identity and revision.',
		},
		{
			name: '400',
			type: 'invalid_argument',
			description: 'A field, cursor or limit is wrong, and the message names it. Retrying unchanged fails the same way.',
		},
		{
			name: '401',
			type: 'missing_authorization',
			description: 'There is no bearer key on the request. Send a Sylphx Access key with the workflows scope the call needs.',
		},
		{
			name: '404',
			type: 'not_found',
			description: 'The schedule does not exist, or is not visible to the key.',
		},
		{
			name: '409',
			type: 'conflict',
			description: 'A fence or an idempotency digest disagrees with what is stored. See the conflicts below.',
		},
		{
			name: '503',
			type: 'store_unavailable',
			description: 'The durable store is not usable. Nothing was admitted; retry when the service is ready.',
		},
		{
			name: '500',
			type: 'internal',
			description: 'An unexpected failure. Retry with the same idempotency key.',
		},
	]}
/>

A schedule mutation can also succeed and report, on the operation it returns,
`platform_place_cell_wake_unavailable`. The schedule row was kept; the wake
that arms it could not be commanded, and the operation says why. That code is
read from the operation document rather than from a transport error, because
the request itself worked.

## Conflicts

A 409 always means the stored state disagrees with your request. What to do
next depends on which fence disagreed.

<PropertyTable
	properties={[
		{
			name: 'Idempotency conflict',
			type: 'same key, different body',
			description: 'A key you already used arrived with a different request. Send the original body to get the original identity back, or a new key if your intent changed.',
		},
		{
			name: 'Revision conflict',
			type: 'expectedRevision',
			description: 'The revision you sent is not the current one, for instance because a tick moved it. Read the schedule again and reapply the change on top of what you read.',
		},
	]}
/>

## Retrying safely

Resend the exact body, with the same `idempotencyKey`, after a timeout, a
dropped connection or a 500. If the first attempt landed you get that identity
back; if it did not, you create it now. Either way there is one record. A
changed body under a used key is a conflict and writes nothing, which is what
makes the retry safe to send.

<RelatedDocs
	links={[
		{
			href: '/docs/jobs/schedules',
			label: 'Schedules',
			description: 'The identity rule, the tick states, pause, and the delete fence.',
		},
		{
			href: '/docs/jobs/quickstart',
			label: 'Quickstart',
			description: 'Create a schedule, read it back and delete it.',
		},
	]}
/>
