---
audience: developers, operators
summary: When things go wrong, start here.
title: Troubleshooting
path: troubleshooting
status: published
---


# Troubleshooting

| | |
|---|---|
| [Getting started](/docs/scaiscribe/troubleshooting/getting-started) | The common cases — auth errors, validation, ingest warnings, sync timeouts. Start here. |
| [Templates](/docs/scaiscribe/troubleshooting/templates) | Template-specific errors — TEMPLATE_FAILED, missing variables, grammar mistakes. |
| [Rendering + jobs](/docs/scaiscribe/troubleshooting/rendering-and-jobs) | Render failures, sync timeouts, job-stuck-pending, presigned URL issues. |
| [Ingestion](/docs/scaiscribe/troubleshooting/ingestion) | Format detection, fidelity-warning catalogue, slow-path recovery. |

## Where to look first when stuck

1. **The error envelope.** Every 4xx/5xx response carries `error.code`, `error.message`, `error.details`, `error.request_id`. The code is machine-readable; the message is operator-readable; `request_id` lets you grep the backend logs.
2. **The fidelity warnings.** Ingest responses always include `spec.fidelity.warnings[]` with structured codes — `INGEST_*` codes are documented and tell you exactly what didn't survive.
3. **The job result_json.** `GET /v1/jobs/{job_id}` returns the full structured error from the worker side when a render fails — usually more detail than the 500 response carried.
4. **The access log.** uvicorn JSON access log on the backend host shows every request with its `request_id`, status, and timing. Grep by `request_id` to pull the matching server-side log.

## Reporting an issue

When something is genuinely broken, include in the bug report:

- The full error envelope (especially `request_id`).
- The full request (method, path, body, headers minus auth).
- The SDK version (Python `pip show scaiscribe`; TS `npm list @scaiscribe/sdk`; .NET `dotnet list package`).
- ScaiScribe backend version, if you have it (visible in `/v1/health` response).

`request_id` is the most useful single field — operators can grep for it across api + worker logs and reconstruct the entire request lifecycle.
