openai/openai-python · error · ValueError

Expected a non-empty value for `batch_id` but received

Error message

Expected a non-empty value for `batch_id` but received {batch_id!r}

What it means

The Batches retrieve method builds GET /batches/{batch_id} and the generated guard raises ValueError when batch_id is empty or None, before any HTTP request. Batch ids look like 'batch_abc123...' and come from batches.create().

Solutions

  1. Store batch.id from client.batches.create(...) and pass that value when polling
  2. Validate batch_id is a non-empty string before retrieve
  3. List batches (client.batches.list()) to recover a lost id

Example fix

# before
batch = client.batches.retrieve(os.environ.get('BATCH_ID'))
# after
batch_id = os.environ['BATCH_ID']
batch = client.batches.retrieve(batch_id)
Defensive patterns

Strategy: validation

Validate before calling

if not batch_id:
    raise ValueError('batch_id is required')
batch = client.batches.retrieve(batch_id)

Type guard

def valid_batch_id(bid: object) -> bool:
    return isinstance(bid, str) and bid.startswith('batch_')

Try / catch

try:
    batch = client.batches.retrieve(batch_id)
except ValueError:
    logger.exception('batch_id was empty')
    raise

Prevention

When it happens

Trigger: client.batches.retrieve('') or retrieve(None); polling a batch whose id was never saved from the create() response.

Common situations: Background jobs that create a batch but fail to persist response.id, then poll with an empty variable; env var containing the batch id left unset.

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/5836b58d26f221b1. Report an issue: GitHub.

Appendix: source

Thrown at src/openai/resources/batches.py:159

        extra_headers: Headers | None = None,
        extra_query: Query | None = None,
        extra_body: Body | None = None,
        timeout: float | httpx2.Timeout | None | NotGiven = not_given,
    ) -> Batch:
        """
        Retrieves a batch.

        Args:
          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not batch_id:
            raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
        return self._get(
            path_template("/batches/{batch_id}", batch_id=batch_id),
            options=make_request_options(
                extra_headers=extra_headers,
                extra_query=extra_query,
                extra_body=extra_body,
                timeout=timeout,
                security={"bearer_auth": True},
            ),
            cast_to=Batch,
        )

    def list(
        self,
        *,
        after: str | Omit = omit,
        limit: int | Omit = omit,
        # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.

View on GitHub (pinned to 9917c6e28e)