# Debugging Podcast Generation Job Failures in Open Notebook

> Effortlessly debug podcast generation job failures in Open Notebook. Query job endpoints, inspect container logs, and validate episode profiles to quickly resolve issues and ensure smooth audio production.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-30

---

**Podcast generation job failures in Open Notebook can be diagnosed by querying the `/podcasts/jobs/{job_id}` endpoint to retrieve error messages from Surreal-Commands records, inspecting Docker container logs for stack traces, and validating that episode profiles contain resolved model configurations.**

Open Notebook generates podcasts asynchronously through a Surreal-Commands job queue. When you trigger a generation request via the API, the system enqueues a background job that executes the `generate_podcast` command. If any step in the pipeline raises an exception, the job status changes to **FAILED** and persists diagnostic details that you can retrieve through the API or container logs.

## How the Podcast Generation Pipeline Works

Understanding the execution flow helps you pinpoint exactly where failures occur.

### Job Submission and Validation

When you request a podcast via the API, `PodcastService.submit_generation_job` in [`api/podcast_service.py`](https://github.com/lfnovo/open-notebook/blob/main/api/podcast_service.py) validates your profiles and content. Lines 36-45 call `submit_command("open_notebook", "generate_podcast", …)` to enqueue the job:

```python

# From api/podcast_service.py

submit_command(
    "open_notebook",
    "generate_podcast",
    {
        "episode_profile": episode_profile,
        "speaker_profile": speaker_profile,
        "content": content,
        "job_id": job_id
    }
)

```

### Command Execution

The Surreal-Commands queue picks up the task and executes the registered `generate_podcast` command defined in [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py) at lines 69-71. Inside this command, the **podcast-creator** library builds the episode, resolves model configurations, writes files, and stores a `PodcastEpisode` record.

## Locating Failure Information

When jobs fail, diagnostic data is available in multiple locations according to the repository's error handling implementation.

### Checking Job Status and Error Messages

Query the job status endpoint to retrieve the `status` field and error details. `PodcastService.get_job_status` in [`api/podcast_service.py`](https://github.com/lfnovo/open-notebook/blob/main/api/podcast_service.py) (lines 15-34) surfaces data from the Surreal-Commands record:

```python

# Retrieve job status programmatically

from open_notebook.api.podcast_service import PodcastService

status = await PodcastService.get_job_status(job_id)
print(status["status"])  # "PENDING", "RUNNING", "FAILED", or "COMPLETED"

print(status["error"])   # Error message if status is FAILED

```

Or via HTTP:

```bash
curl http://localhost:8000/api/podcasts/jobs/{job_id}

```

### Inspecting Container Logs

The `generate_podcast_command` in [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py) uses `loguru` for logging. In Docker deployments, view detailed stack traces by inspecting container logs:

```bash
docker logs open-notebook-container

```

Detailed exception traces are caught at lines 88-99 and re-raised as `RuntimeError` with hints for GPT-5 models, providing context for LLM-specific failures.

### Debugging Profile Validation Errors

Profile validation occurs early in `submit_generation_job` (lines 46-56). If you pass invalid episode or speaker profile names, the service raises an error before enqueuing the job. Verify available profiles using:

```bash
curl http://localhost:8000/api/podcasts/episode-profiles
curl http://localhost:8000/api/podcasts/speaker-profiles

```

### Resolving Model Configuration Issues

Inside the command execution, each profile's `resolve_*_config` method may raise `ValueError` if model fields are empty (lines 102-118 in [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py)). Confirm that outline, transcript, and TTS models are configured in your profiles via the UI or database.

## Common Failure Causes and Solutions

Based on the implementation in [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py), these specific errors occur most frequently:

- **Invalid API Key**: Credentials for TTS or LLM providers are missing or expired. Update keys in **Settings → Credentials** or edit the credential record directly.
- **Model Not Found**: The model name in your profile does not exist in the Esperanto model registry. Select a valid model from **Models → Add Configuration** and re-assign it to the profile.
- **Rate Limit Exceeded**: Provider throttling blocks your calls. Wait several minutes before retrying, or upgrade to a higher-quota plan.
- **Provider Unavailable**: External services are down. Check the provider's status page and retry later.
- **Invalid JSON Output (GPT-5)**: The LLM wraps output in markdown code blocks or returns malformed JSON. The error handling at lines 88-99 provides specific hints for GPT-5 model failures.

## Summary

- Query `/podcasts/jobs/{job_id}` or call `PodcastService.get_job_status()` to retrieve failure details from Surreal-Commands records.
- Check Docker container logs for full stack traces emitted by `loguru` in [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py).
- Validate that episode and speaker profile names exist before submission via [`api/podcast_service.py`](https://github.com/lfnovo/open-notebook/blob/main/api/podcast_service.py) validation logic.
- Ensure all models are properly configured in profiles to avoid `ValueError` during `resolve_*_config` calls.
- Update expired credentials and verify model registry entries to resolve authentication and resolver errors.

## Frequently Asked Questions

### How do I check if a podcast generation job failed?

Query the job status endpoint using the job ID returned when you submitted the request. The `PodcastService.get_job_status` method in [`api/podcast_service.py`](https://github.com/lfnovo/open-notebook/blob/main/api/podcast_service.py) returns a status field that will be set to "FAILED" if an error occurred, along with an error message containing the exception details.

### Where are the detailed error logs for podcast generation?

Detailed logs are written to stdout via `loguru` from within [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py). In Docker environments, access these using `docker logs <container_name>`. The command catches exceptions at lines 88-99 and re-raises them as `RuntimeError` with additional context for GPT-5 model failures.

### Why does my podcast job fail immediately after submission?

Immediate failures typically indicate validation errors in `PodcastService.submit_generation_job` (lines 46-56). The service validates that your episode and speaker profile names exist in the database before enqueuing the job. Verify your profiles exist via the `/api/podcasts/episode-profiles` and `/api/podcasts/speaker-profiles` endpoints.

### What causes "Model not found" errors during podcast generation?

This error occurs when `resolve_*_config` methods in [`commands/podcast_commands.py`](https://github.com/lfnovo/open-notebook/blob/main/commands/podcast_commands.py) (lines 102-118) cannot locate the specified model in the Esperanto registry. This happens when a profile references a model that was deleted or never configured. Ensure all outline, transcript, and TTS models are properly set in your profile configurations.