> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heychocolate.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error codes, formats, and handling for the Hey Chocolate GraphQL API.

## Error format

```json theme={null}
{
  "data": null,
  "errors": [
    {
      "message": "Human-readable error description",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["products", "edges", 0, "node"],
      "extensions": {
        "code": "ERROR_CODE",
        "requestId": "req_abc123"
      }
    }
  ]
}
```

## Error codes

### Authentication & Authorization

| Code              | Description                                |
| ----------------- | ------------------------------------------ |
| `UNAUTHENTICATED` | Missing or invalid API key                 |
| `INVALID_API_KEY` | API key is malformed or revoked            |
| `FORBIDDEN`       | API key lacks required permissions or tier |

### Validation

| Code               | Description               |
| ------------------ | ------------------------- |
| `VALIDATION_ERROR` | Input validation failed   |
| `INVALID_ARGUMENT` | Invalid argument value    |
| `REQUIRED_FIELD`   | Required field is missing |
| `INVALID_FORMAT`   | Field format is incorrect |

### Resources

| Code               | Description                                        |
| ------------------ | -------------------------------------------------- |
| `NOT_FOUND`        | Requested resource does not exist                  |
| `ALREADY_EXISTS`   | Resource with this identifier already exists       |
| `DEPENDENCY_ERROR` | Operation depends on a missing or invalid resource |

### Rate Limiting & Quotas

| Code                  | Description          |
| --------------------- | -------------------- |
| `RATE_LIMIT_EXCEEDED` | Too many requests    |
| `QUOTA_EXCEEDED`      | Daily quota exceeded |

### Server

| Code                  | Description                       |
| --------------------- | --------------------------------- |
| `INTERNAL_ERROR`      | Unexpected server error           |
| `SERVICE_UNAVAILABLE` | Service temporarily unavailable   |
| `RENDER_TIMEOUT`      | Visualisation rendering timed out |
| `CALCULATION_ERROR`   | Impact calculation failed         |

## Partial success

GraphQL can return partial data alongside errors:

```json theme={null}
{
  "data": {
    "products": {
      "edges": [
        { "node": { "id": "prod_abc123", "name": "Product A", "impactScore": { "co2Equivalent": 12.4 } } }
      ]
    }
  },
  "errors": [
    {
      "message": "Failed to load impact score for product prod_def456",
      "path": ["products", "edges", 1, "node", "impactScore"],
      "extensions": { "code": "CALCULATION_ERROR" }
    }
  ]
}
```

## Validation error details

```json theme={null}
{
  "errors": [
    {
      "message": "Validation failed",
      "extensions": {
        "code": "VALIDATION_ERROR",
        "details": {
          "fields": [
            { "field": "quantity", "message": "Must be greater than 0" },
            { "field": "transportMethod", "message": "Invalid value. Allowed: TRUCK, RAIL, SHIP, AIR" }
          ]
        }
      }
    }
  ]
}
```

## Retry strategy

For `RATE_LIMIT_EXCEEDED` and `SERVICE_UNAVAILABLE` errors:

1. Check `extensions.retryAfter` for the recommended wait time
2. If not provided, use exponential backoff: 1s, 2s, 4s, 8s
3. Maximum 5 retries
