> For the complete documentation index, see [llms.txt](https://docs.parasail.io/parasail-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.parasail.io/parasail-docs/products/quickstart/troubleshooting.md).

# Troubleshooting

This page covers the most common problems you'll hit when submitting and processing batch jobs, and how to resolve them. Parasail's batch service is 100% compatible with the OpenAI batch API, so the file formats, status values, and error codes described here match the OpenAI batch model.

## JSONL validation failures

A batch input file is a `.jsonl` file where **each line is a single, complete JSON object** representing one request. A batch will fail validation if any line is malformed or missing required fields.

Each request line must include:

* `custom_id`: a unique value you create so you can later match outputs to inputs.
* `method`: the HTTP method, currently `POST`.
* `url`: one of `/v1/chat/completions` or `/v1/embeddings`.
* `body`: the same JSON body you would send to an interactive request.

Common causes of validation failures:

* **Malformed lines.** A line isn't valid JSON (trailing comma, unescaped quote, or a request split across multiple lines). Each request must be exactly one line.
* **Missing required keys.** A line is missing `custom_id`, `method`, `url`, or `body`.
* **Duplicate or missing `custom_id`.** Each `custom_id` should be unique so responses can be matched back unambiguously.
* **Wrong `url`.** Only `/v1/chat/completions` and `/v1/embeddings` are supported.
* **`stream` set in the body.** For chat completions, `stream` must be omitted or set to `false`.

To debug, validate the file locally before submitting:

```python
import json

with open("example_batch_input.jsonl") as f:
    for i, line in enumerate(f, start=1):
        try:
            req = json.loads(line)
        except json.JSONDecodeError as e:
            print(f"Line {i} is not valid JSON: {e}")
            continue
        for key in ("custom_id", "method", "url", "body"):
            if key not in req:
                print(f"Line {i} is missing required key: {key}")
```

See [Batch file format](/parasail-docs/products/quickstart/file-format.md) for the full request and response schema.

## File-size and request-count limits exceeded

Parasail limits the size of each batch input file:

* Up to **50,000 requests** (lines) per input file.
* Up to **1000 MB** total input file size.

Workloads that exceed either limit must be split into multiple batches. If you use the [Parasail Batch Helper Library](https://github.com/parasail-ai/openai-batch), `add_to_batch` raises a `ValueError` when the file-size or request-count limit for the provider is exceeded. Catch it and roll over into a new batch:

```python
from openai_batch import Batch

def submit_in_chunks(requests):
    batch_ids = []
    batch = Batch()
    for req in requests:
        try:
            batch.add_to_batch(**req)
        except ValueError:
            # Current batch is full; submit it and start a new one.
            batch_ids.append(batch.submit())
            batch = Batch()
            batch.add_to_batch(**req)
    batch_ids.append(batch.submit())
    return batch_ids
```

If you submit through the API or Batch UI directly, split the `.jsonl` file yourself so that each file stays under both limits.

## Jobs stuck in `validating` or `in_progress`

A batch moves through `validating`, then `in_progress`, then a terminal state (`completed`, `failed`, `expired`, or `cancelled`). Jobs run on Parasail's servers, so a long-running batch is processed to completion even if your local script crashes, resets, or exits.

You do **not** need to keep a process running to wait for results. Record the batch ID at submission time and resume monitoring later from a separate process:

```python
from openai_batch import Batch
import time

with Batch(batch_id="batch-tclfzwczcd",
           output_file="mybatch.jsonl") as batch:
    while True:
        status = batch.status()
        print(f"Batch status: {status.status}")
        if status.status in ["completed", "failed", "expired", "cancelled"]:
            break
        time.sleep(60)  # Check every minute

    output_path, error_path = batch.download()
    print(f"Output saved to: {output_path}")
```

You can also track progress, view metadata, or cancel a queued or running batch from the [Batch UI](/parasail-docs/products/quickstart.md#parasail-batch-ui).

## Partial failures

A batch can complete with some requests succeeding and others failing. Failures are reported **per request** rather than failing the whole batch, so always inspect each output line.

Two things to keep in mind when reading output:

* **The order of responses may differ from the order of requests** in the input file.
* **Match responses to requests using `custom_id`**, not by line position.

Each output line contains a `response` object with a `status_code`. A `200` means the request succeeded; any other code is the same HTTP error you would have received for that request interactively.

```python
import json

results = {}
with open("mybatch.jsonl") as f:
    for line in f:
        record = json.loads(line)
        custom_id = record["custom_id"]
        response = record.get("response") or {}
        status = response.get("status_code")
        if status == 200:
            results[custom_id] = response["body"]
        else:
            print(f"{custom_id} failed with status {status}: {record.get('error')}")
```

Failed requests can be collected and resubmitted in a new batch.

## Quota errors

If a batch can't be scheduled because your organization is out of GPU capacity, you'll see an **"Insufficient quota"** message. By default, each organization has a quota of **4 GPUs**, shared across both Batch and Dedicated services regardless of GPU type. A single batch that requires more GPUs than your remaining quota will be rejected.

To resolve this:

* Wait for other jobs that are consuming GPUs to finish, or
* Request more capacity through the Quota Increase form. See [GPU quota](/parasail-docs/operate-in-production/limits-and-quotas.md#gpu-quota) for details. Increases up to 8 GPUs are available without additional justification.

## Authentication errors (401)

The batch tooling reads your key from the `PARASAIL_API_KEY` environment variable. A `401` response, or an error about a missing API key, usually means the key isn't set or isn't valid.

* Confirm the variable is set in the environment that runs your script:

  ```bash
  PARASAIL_API_KEY=<your-key> python3 test_batch.py
  ```
* Store the key in a `.env` or shell profile rather than pasting it into code, where it can be leaked.
* Create or rotate keys at <https://www.saas.parasail.io/keys>.
* When using the OpenAI SDK directly, point the client at Parasail and pass the key explicitly:

  ```python
  import os
  from openai import OpenAI

  client = OpenAI(
      base_url="https://api.parasail.io/v1",
      api_key=os.environ["PARASAIL_API_KEY"],
  )
  ```

## Output parsing

Results are returned as an output `.jsonl` file, with one response per line. Parse it line by line as JSON and pull `response.body` out of each record (see the partial-failures snippet above for matching on `custom_id`).

For embeddings, Parasail strongly recommends submitting requests with `"encoding_format": "base64"`, which returns each embedding as a Base64-encoded binary array instead of a plain-text float array. This typically reduces output file size by nearly 4x with no loss of precision, but it means you must **decode** the value before use:

```python
import base64
import json
import numpy as np

with open("embeddings-output.jsonl") as f:
    for line in f:
        record = json.loads(line)
        for item in record["response"]["body"]["data"]:
            vector = np.frombuffer(base64.b64decode(item["embedding"]), dtype=np.float32)
            # use vector ...
```

## Next steps

* [Quick start](/parasail-docs/products/quickstart.md)
* [Batch file format](/parasail-docs/products/quickstart/file-format.md)
* [Batch API Reference](/parasail-docs/api-reference/batch-api.md)
* [GPU quota](/parasail-docs/operate-in-production/limits-and-quotas.md#gpu-quota)
