Errors and retries
Each error code, what it means, what to do, and when a second try is safe.
Every error has the same shape, and the codes are stable, so your code can branch on error.code.
{
"error": {
"code": "FORBIDDEN",
"message": "This key or connection can't search these drives: drv_4h7k2m9q8r1t5v6w3x0y.",
"drive_ids": ["drv_4h7k2m9q8r1t5v6w3x0y"]
}
}| Field | When it's present | Meaning |
|---|---|---|
code | Always | A stable name for programs. |
message | Always | A sentence for people. Don't branch on it, because the wording can change. |
search_id | Errors from the search itself, such as TIMEOUT | The ID of the search, for support. A request refused before the search starts has no search_id. |
drive_ids | FORBIDDEN and DRIVE_UNAVAILABLE from a search | The drives the error is about. |
A search whose passages don't answer the question isn't an error: it comes back with status 200 and the nearest passages, and the list is empty only when nothing in the drives comes close. See When nothing answers.
All codes
| Status | Code | What it means | What to do | Try again? |
|---|---|---|---|---|
| 400 | INVALID_REQUEST | A field is missing or wrong. | Read message and correct the request. | Not without a change |
| 401 | UNAUTHENTICATED | The key is missing or doesn't work. | Check the header and the key. See Authentication. | Not without a change |
| 402 | BALANCE_EXHAUSTED | The team's balance can't pay for the call. | A team owner or admin adds money. See Pricing and billing. | After the balance has money |
| 403 | FORBIDDEN | The key's scope doesn't allow the call, or a search names a drive the key can't reach. | For a call that changes content, use a key with the Read and write scope. For a search, check drive_ids. | Not without a change |
| 404 | NOT_FOUND | The drive, document, upload or operation doesn't exist, or the key can't reach it. ByteRover answers the same way in both cases, so a caller without access learns nothing from an ID. A read also returns it when the document has no such page, slide, sheet or section. | Check the ID, and check the key's drives with GET /v1/key. For a read, check the selector. | No |
| 409 | VERSION_MISMATCH | The document changed after you read it. | Fetch the document again, then repeat the call with its new version as expected_version. | Yes, after a new read |
| 409 | CONFLICT | A read named a revision that isn't the document's current one. | Search again for current offsets, or leave revision out. See Read a document. | Not without a change |
| 409 | NAME_TAKEN | A folder or document already exists at the new path. | Choose another path. | Not without a change |
| 409 | FOLDER_NOT_EMPTY | You tried to delete a folder that still has documents. | Move or delete the documents first. | After the change |
| 409 | UPLOAD_CLOSED | The upload has finished or expired. | Start a new upload. | With a new upload |
| 409 | IDEMPOTENCY_MISMATCH | You reused an Idempotency-Key with a different request. | Use a new key for each new request. | With a new key |
| 500 | INTERNAL_ERROR | An unexpected error in ByteRover. | Try once more. If it fails again, send the search_id or the operation ID to support. | Once |
| 503 | SEARCH_UNAVAILABLE | Search can't run right now. | Wait a short time, then repeat with the same effort. | Yes |
| 503 | DRIVE_UNAVAILABLE | A drive can't be searched right now. drive_ids names it. | Wait a short time, then repeat. | Yes |
| 503 | STORAGE_UNAVAILABLE | Uploads can't be accepted right now. | Wait a short time, then repeat. | Yes |
| 503 | QUEUE_UNAVAILABLE | The file was saved, but its processing couldn't be queued, so its operation is failed. | Wait a short time. Then send a small text document again, or start a new upload to the same path; completing the same upload again doesn't queue it. | With a new request |
| 504 | TIMEOUT | The search took too long. | Repeat with the same effort. | Yes |
How to retry
Retry only 5xx errors and failed connections. A 4xx error keeps returning the same result until you change the request.
Back off between tries: wait one second, then double the wait each time (1, 2, 4, 8 seconds), and stop after four or five tries.
Keep the same effort when you retry. ByteRover never lowers the effort after an error, and your code must not do so without your user knowing, since a medium result in place of a high one is a different product.
Send an idempotency key with calls that change content. That way a retry made after the first call has ended doesn't repeat the work.
Idempotency
On any call other than a GET, you can send an Idempotency-Key header with a value of your choosing, such as a UUID. If you send the same request with the same key within 24 hours, ByteRover returns the first response instead of doing the work again.
That only applies once the first call has finished successfully. If you send the retry while the first call is still open, both can run.
curl -X PUT https://byterover.ai/api/v1/drives/drv_4h7k2m9q8r1t5v6w3x0y/documents/by-path \
-H "Authorization: Bearer $BYTEROVER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2a9e-4b7d-4c3a-9e2f-8d5b1a7c0e34" \
-d '{ "path": "/notes/standup.md", "text": "Decisions of 10 November." }'A key is 1 to 255 characters long. Reusing a key with a different request to the same operation returns IDEMPOTENCY_MISMATCH. Only successful responses are kept, so after an error the same key runs the request again.
Versions
Drives and documents carry a version number that changes whenever they do. To avoid overwriting another caller's change, send the version you read as expected_version when you change a document's tags, move it or delete it. If the document has changed in the meantime, you get VERSION_MISMATCH.
Operations that fail later
An upload returns immediately and the work continues in an operation, which can fail even though your call succeeded. Always check the final status:
{
"id": "op_3g6j9m2p5s8v1y4b7e0h",
"kind": "ingest",
"status": "failed",
"error": { "code": "SUPERSEDED", "message": "A newer revision of the document replaced this one." },
"retry_after_ms": null
}Here, a newer upload to the same path replaced the revision, so there's nothing to fix. Follow the newer upload's operation instead.
When ByteRover can't read a file, the operation fails, the document's status becomes failed, and its error field gives the reason. Fix the file and upload it again to the same path. A PDF that's only images fails with the code IMAGE_ONLY_PDF_UNSUPPORTED, on the operation and in the document's error_code field: ByteRover can't read it yet (see Scanned PDFs). For other failures error_code is null.
Get help
Send support the search_id of a search or the id of an operation, and they can find the call from that. You don't need to send your question or your files.