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

# Python SDK logging and troubleshooting

> Read event delivery errors, trace batch activity, and use verbose logging to debug missing traces.

If your application logs `Error sending events.`, start with the error already in your application logs. Python SDK [1.4.42](https://pypi.org/project/lunary/1.4.42/) and later include a reason and a batch size with verbose logging off. Check the version in the environment that runs your application with `python -m pip show lunary`.

## Read a production error

Leave `LUNARY_VERBOSE` unset or set it to `false`. The `lunary` logger defaults to `WARNING`, and its child `lunary.consumer` logs event delivery failures at `ERROR`. Your application's Python logging handlers can capture these records alongside your other logs. If you configure log filtering, include `lunary.consumer` at `ERROR` and keep the timestamp and timezone.

```text theme={null}
Error sending events. The endpoint rate-limited the request. Batch will not be retried. error_type=HTTPError http_status=429 batch_size=2.
```

Here, the endpoint returned HTTP 429 for a request containing two events. The SDK removed that batch from its in-memory queue before sending it and will not send it again. One failed batch produces one error line, even when it contains many events. `http_status=n/a` means the SDK has no HTTP error status to report. For example, a read timeout can occur after the server received the batch, so the event count alone cannot tell you how many events were lost.

If an older SDK prints only `Error sending events.`, use the timestamp to look up the request to `/v1/runs/ingest` in your gateway or ingestion logs. For hosted Lunary, share the timestamp, timezone and SDK version with support. Upgrading adds the reason to future errors.

### HTTP responses

| Status | What the message tells you | First check |
| - | - | - |
| 400 or 422 | The endpoint rejected the request or could not validate the batch. | Check the event format and the SDK version producing it. |
| 401 | The API can distinguish `Invalid API key.`, `This project does not exist.`, an invalid access token, unauthorized project access, or an organization key used on the wrong route. Other 401s give a general authentication hint. | Verify that the running process uses the intended **project** key and endpoint. |
| 402 | `Incorrect project id format.` points to the project ID. `Payment is required to access this workspace.` points to billing. | Follow the reason on the line. If it only says to check the ID and workspace billing, check both. |
| 403 or 404 | Access was denied, or the ingestion endpoint could not be found. | For 403, check project permissions. For 404, check `LUNARY_API_URL` and proxy routing. The SDK appends `/v1/runs/ingest` to the base URL. |
| 408 | The endpoint timed out waiting for the request. | Compare request duration and timeout settings in gateway logs. |
| 413 | `The event batch is too large.` | Check input, output and metadata sizes and the proxy's request-size limit. `batch_size` counts events, not bytes. |
| 429 | The endpoint rate-limited the request. | Compare bursts of traffic with limits on the service or gateway. |
| 502, 503 or 504 | The gateway got an invalid upstream response, the service or gateway was unavailable, or the gateway timed out. | Check gateway and ingestion health at the reported time. |
| Other HTTP errors | Other 5xx responses identify a server or gateway failure. Other status codes use a generic HTTP message. | Correlate the exact status and timestamp with the endpoint logs. |

### Failures without an HTTP status

| What you see | What to check |
| - | - |
| `API key not found. Please provide an API key.` | The batch stopped before any HTTP request. Check that the worker process has `LUNARY_PUBLIC_KEY` or an explicitly configured project key. If both environment keys are set, the SDK reads `LUNARY_PRIVATE_KEY` first. |
| `ConnectionError` or `ProxyError` | From the application's host or container, check DNS, network access to the configured API host, and proxy routing. |
| `SSLError` | Check the certificate chain and CA trust on the machine or container opening the connection. |
| `ConnectTimeout`, `ReadTimeout` or `Timeout` | A connect timeout occurred while connecting. A read timeout means the endpoint did not respond in time. Correlate a generic timeout with gateway timings to locate the delay. |
| `The SDK could not encode the event batch.` | Encoding failed before the POST. Reproduce the event with small, serializable sample inputs, outputs and metadata. |
| `The SDK could not complete the ingestion request.` | Use the accompanying `error_type`, SDK version and timestamp to narrow down the failure. |

## Trace batch activity without logging event contents

If errors are quiet but traces seem delayed, you can watch the worker in a short diagnostic run. Start with verbose mode off, then enable DEBUG on the consumer logger only. In an application that already configures logging, use its existing handler and make sure its level admits DEBUG from `lunary.consumer`.

```python theme={null}
import logging
import lunary

# For a standalone diagnostic script.
logging.basicConfig(
    format="%(asctime)s %(levelname)s %(name)s %(message)s",
    datefmt="%Y-%m-%dT%H:%M:%S%z",
)
logging.getLogger("lunary.consumer").setLevel(logging.DEBUG)
```

Run one monitored operation. A successful send can produce the following messages (formatter prefixes omitted).

```text theme={null}
Sending 2 events.
Sending events to https://api.lunary.ai
Events sent. status_code=200
```

The first line shows that the worker picked up a batch. The second shows the configured API base URL. The last shows that the request completed with HTTP 200. The worker does not inspect per-event results in the response. If the dashboard still looks empty, check the project and time filter and correlate the send time with ingestion logs. Review any custom endpoint URL before sharing these lines.

## Use verbose logging for one reproduction

For a serialized event or a send traceback, start a fresh process with `LUNARY_VERBOSE=true` **before importing** `lunary`. Both `true` and `True` enable this behavior. Run your own reproduction script against a test project with synthetic input.

```bash theme={null}
LUNARY_VERBOSE=true python reproduce.py
```

At startup the SDK adds a DEBUG handler that writes to stderr and turns off propagation from `lunary` to the root logger. Look for `Add event:` followed by serialized event data, then the consumer's batch messages. `Add event:` means the event was queued. A failed send also includes a Python traceback. To return to normal logging, end that process and start the application with the variable unset or `false`.

In a running application, `lunary.config(verbose=True)` enables send-error tracebacks and the SDK's event-debug code. The existing logger and handler levels still control whether DEBUG records appear. This call does not install the startup stderr handler. If your application passes a custom `ssl_verify` setting, retain it when calling `config`. Changing a logger level alone does not enable verbose event serialization or send-error tracebacks.

Verbose output can include prompts, model outputs, user metadata, endpoint URLs and an explicitly supplied event key. Share the standard delivery error line for production investigations. Review and redact any verbose output or traceback before sharing it.

## Recognize tracking and integration messages

| Message or prefix | What it means |
| - | - |
| `A run cannot be its own parent.` | The SDK rejected that run. Give the child a different run ID from its parent. |
| A warning about a missing supported client package, client version, or LangChain `app_id` | Check the integration's setup and the versions installed in the process that creates the client or callback. |
| An exception in `track_event`, `Error parsing openai output`, or an exception in a callback such as `on_llm_end` | The failure occurred while tracking, parsing a provider response, or handling a callback. Reproduce it with the same SDK and provider versions and a synthetic input of the same shape. These integration errors can include a traceback even in normal mode. |

When asking support to investigate, include the SDK version, timestamp with timezone, whether you use hosted or self-hosted Lunary, and the exact standard error line. For an integration error, include the provider and client version as well. Keep API keys and event contents out of the report.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.