---
title: "Errors — GanttFather API"
description: "RFC 9457 problem documents, the stable code table, and the two uncoded edge cases."
canonical: "https://ganttfather.com/docs/api/errors/"
locale: "en"
category: "product"
---

# Errors — GanttFather API

API reference [AI assistants (MCP)](https://ganttfather.com/docs/ai-agent/)

## Getting started

- [Introduction](https://ganttfather.com/docs/api/introduction/)
- [Authentication](https://ganttfather.com/docs/api/authentication/)
- [Pagination](https://ganttfather.com/docs/api/pagination/)
- [Rate limits & quotas](https://ganttfather.com/docs/api/rate-limits/)
- [Errors](https://ganttfather.com/docs/api/errors/)

## Projects

- [GET List projects](https://ganttfather.com/docs/api/list-projects/)
- [GET Get project](https://ganttfather.com/docs/api/get-project/)

## Tasks

- [GET List tasks](https://ganttfather.com/docs/api/list-tasks/)
- [GET Get task](https://ganttfather.com/docs/api/get-task/)
- [POST Create task](https://ganttfather.com/docs/api/create-task/)
- [PATCH Update task](https://ganttfather.com/docs/api/update-task/)
- [DELETE Delete task](https://ganttfather.com/docs/api/delete-task/)
- [POST Reorder tasks](https://ganttfather.com/docs/api/reorder-tasks/)
- [PUT Set assignees](https://ganttfather.com/docs/api/set-assignees/)

## Dependencies

- [GET List dependencies](https://ganttfather.com/docs/api/list-dependencies/)
- [PUT Set dependencies](https://ganttfather.com/docs/api/set-dependencies/)
- [POST Add dependency](https://ganttfather.com/docs/api/add-dependency/)
- [DELETE Remove dependency](https://ganttfather.com/docs/api/remove-dependency/)

## Resources

- [GET List resources](https://ganttfather.com/docs/api/list-resources/)
- [POST Create resource](https://ganttfather.com/docs/api/create-resource/)
- [PATCH Update resource](https://ganttfather.com/docs/api/update-resource/)
- [DELETE Delete resource](https://ganttfather.com/docs/api/delete-resource/)

## Members

- [GET List members](https://ganttfather.com/docs/api/list-members/)

 Getting started / **Errors**

# Errors

 Updated Jul 4, 2026

 The API uses conventional HTTP status codes: 2xx means your request succeeded, 4xx means something about the request needs to change, and 5xx means the failure was on our side.

 Errors are RFC 9457 problem documents with a stable machine code and a traceId you can quote to support (also on the X-Trace-Id header):

 {
 "title" : "Group task fields are derived" ,
 "status" : 400 ,
 "detail" : "Cannot set progress or status on a group task directly." ,
 "code" : "parent_task_rollup" ,
 "traceId" : "6e0f…"
 }

 Match on code , never on the title text or the HTTP status alone — title is a human-readable summary and may change; code is the stable contract.

## Response codes

 Status Meaning

 200 OK Request succeeded.

 201 Created A resource (task, dependency, resource) was created.

 204 No Content Request succeeded; there’s nothing to return (deletes).

 400 Bad Request The request body or parameters failed validation — see code .

 401 Unauthorized Missing, wrong, or revoked token.

 403 Forbidden Authenticated, but not allowed to do this — see code .

 404 Not Found The resource doesn’t exist, or you can’t reach it (the API never distinguishes the two).

 409 Conflict A concurrent write or a reused Idempotency-Key with a different body.

 429 Too Many Requests Rate limit or daily quota exceeded — see [Rate limits & quotas →](https://ganttfather.com/docs/api/rate-limits/).

 5xx Something failed on our side. Safe to retry with backoff.

## Error codes

 Code Status Meaning

 forbidden 403 ReadOnly token attempting a write, or writing to a project you can’t write to

 project_read_only 403 the project is locked (lapsed / admin lock / pending deletion) — reason in detail

 user_agent_required 403 the request had no (or an empty) User-Agent header — see [Authentication →](https://ganttfather.com/docs/api/authentication/)

 missing_argument 400 a required field (e.g. name on create) was absent

 invalid_date / invalid_dates 400 unparseable date / end before start

 invalid_color 400 color must be #RRGGBB

 invalid_assignee 400 an assignee id isn’t a member or resource of the project

 invalid_parent 400 parent in another project, self-parent, or a hierarchy cycle

 parent_task_rollup 400 direct progress/status on a group task

 too_deep 400 delete would cascade through more than 20 levels

 too_many_items 400 a reorder batch over 1,000 items, or a dependency set over the per-task cap

 invalid_dependency / invalid_lag / invalid_dependency_type / cross_project / not_siblings / cycle_detected / graph_too_large 400 dependency graph rules

 conflict 409 concurrent modification lost — re-read and retry

 idempotency_conflict 409 an Idempotency-Key was reused with a different body

 rate_limited / quota_exceeded 429 see [Rate limits & quotas →](https://ganttfather.com/docs/api/rate-limits/) — honor Retry-After

 Two edge cases don’t carry a code : a **malformed JSON body or wrong-typed field** is rejected by the request binder as a bare 400 (validation problem document, no code ), and anything you **can’t reach** is a plain 404 with no body detail — by design.

## Idempotency and caching

 POST endpoints that create things accept an Idempotency-Key header — replaying the same key and body returns the original response instead of creating a duplicate; the same key with a different body is 409 idempotency_conflict . Heavy GETs return a strong ETag ; send it back as If-None-Match to get a cheap 304 Not Modified when nothing changed. See [Rate limits & quotas →](https://ganttfather.com/docs/api/rate-limits/) for both in full.

## Handling errors

- **Check the code field**, not the HTTP status text — the same status (e.g. 400 ) covers several distinct codes.

- **Retry 429 s with backoff**, honoring the Retry-After header rather than a fixed delay.

- **Don’t retry 4xx other than 429 ** without changing the request — the request itself needs to change first.

- ** 5xx is always safe to retry** with exponential backoff; if it persists, quote the traceId to support.
