Scope and completeness
This is exhaustive for explicit error codes, preflight issue codes, deliberate failure messages, and validation branches defined in the current Tours Listing Video path. It cannot enumerate arbitrary runtime text from operating-system failures, FFmpeg, Supabase, Trigger.dev, Resend, or third-party provider response bodies. Those variable failures are listed by boundary and normalized outcome.
Important: most internal failures should not be shown verbatim to customers. The public email currently says creation failed, confirms the Listing is saved, and links back to the Listing. Detailed causes belong in the Listing UI only when they produce a clear customer action; raw diagnostics belong in logs and Internal QA.
Failure landscape
The same underlying outage can surface at more than one layer. Counts below describe contracts, not mutually exclusive incidents.
Catalog
1. Request, access, credits, and task startup
| Error / response | Why it happens | Recommended surface |
|---|---|---|
SIGN_IN_REQUIRED“Sign in to access Tours.” | No authenticated Supabase user exists for the request. | Sign in |
TOURS_UNAVAILABLE“Tours is not available for this account.” | The TOURS feature flag is off or the account is not on the required Pro tier. | Account action |
LISTING_LOOKUP_FAILED | The scoped Listing query returned a database error. | Retry |
LISTING_NOT_FOUND | The Listing id is absent, belongs to another user/Profile, or is unavailable under the active Profile scope. | Open Listings |
LISTING_ARCHIVED | The request requires an open Listing, but the Listing has been archived. | Use active Listing |
INVALID_RENDER_OPTIONS | The options payload is not an object; contains an unsupported top-level key; has an invalid render mode; uses non-boolean reuse flags; has invalid transition settings; or supplies a non-string script/Scene model id. | Client contract bug |
CREATION_NOT_CONFIRMED | Initial creation was requested before Photo Permission and the Listing Overview were confirmed. | Finish Overview |
OVERVIEW_INCOMPLETE | A later Listing Video was requested while the saved creation plan is still incomplete. | Finish Overview |
ACTIVE_PROFILE_MISSING | The user has no active Profile when credits and provider ownership are resolved. | Choose Profile |
INSUFFICIENT_CREDITS | The AiM credit reservation reports a balance below the calculated base, per-Scene, and Presenter cost. This is separate from a connected provider account running out of its own credits. | Add AiM credits |
PRICING_FAILED | The credit system cannot calculate or reserve a valid price for the requested render. | Retry |
RUN_CREATION_FAILED | Preflight passed, but reusable assets could not be invalidated, renderable context could not be loaded, or the database could not create/complete the render-run row. | Engineering |
TRIGGER_ENQUEUE_FAILED“Could not start the render task. Try again.” | Trigger.dev did not return a run handle within three seconds, rejected the enqueue, or the enqueue call threw. | Retry |
SUPERSEDED_BY_NEW_RENDER | A newer Listing Video was started for the same Listing. The older active run is cancelled intentionally. | Not a failure |
USER_CANCELLED | The user explicitly stopped a queued or running Listing Video. | Not a failure |
Exact option validation variants
options must be an object; unsupported option key; invalid renderMode; non-boolean reuseExistingAssets; non-object reuse; unsupported or non-boolean reuse.*; non-object sceneTransitions; unsupported sceneTransitions.*; unsupported transition effect; non-string scriptPlanningModelId; non-string sceneClipProviderModelId.
2. Authoritative preflight blockers (21 codes)
| Code | Why it happens | Recommended surface |
|---|---|---|
project_not_found | The Listing cannot be loaded for this user and Profile. | Open Listings |
project_archived | The Listing status is not open. | Use active Listing |
invalid_creation_plan | The persisted creation-plan schema is unsupported or invalid. | Create new video |
missing_listing_media_permission | A valid creation plan exists but Photo Permission has not been acknowledged. | Confirm permission |
no_included_scenes | No Scene remains included in the Listing Video. | Add a Scene |
missing_authoritative_source_photo | An included Scene does not have its required main Photo. | Add Photo |
unsupported_render_mode | The mode is neither ken_burns_ffmpeg nor provider_image_to_video. | Contract/config |
missing_custom_scene_movement | A provider image-to-video Scene uses Custom Scene Movement but its instructions are empty. | Describe movement |
missing_elevenlabs_key | The resolved narration strategy requires ElevenLabs, but the active Profile has no usable key. | Connect ElevenLabs |
missing_elevenlabs_voice_id | ElevenLabs narration is selected but no Narration Voice id is frozen into the run. | Choose Voice |
elevenlabs_voice_ineligible | The selected voice exists but is processing, not ready, failed, unsupported, incomplete, or unavailable. | Choose/repair Voice |
elevenlabs_voice_catalog_unavailable | The key cannot be loaded, the voice lookup fails/times out, or ElevenLabs returns invalid catalog data. | Reconnect/retry |
missing_narration_voice_id | A HeyGen combined Presenter flow resolves no default voice for the selected Presenter. | Choose Presenter |
missing_heygen_key | The resolved Presenter strategy requires HeyGen, but the active Profile has no usable key. | Connect HeyGen |
missing_heygen_avatar_id | Presenter Presentation is selected but no HeyGen avatar/look id is configured. | Choose Presenter |
missing_heygen_avatar_placement | Presenter Presentation is selected without saved Presenter positioning. | Position Presenter |
heygen_presenter_ineligible | The selected Presenter is unavailable, processing, failed, missing metadata/preview/default voice, or incompatible with the required HeyGen engine. | Choose/repair Presenter |
heygen_presenter_catalog_unavailable | The key cannot be loaded, the Presenter lookup fails/times out, or HeyGen returns invalid catalog data. | Reconnect/retry |
listing_media_unreadable | Supabase cannot read one or more main Photos from listing-media storage. | Re-upload Photo |
provider_media_unreachable | The signed source URL exists but cannot be reached from the provider-visible origin, commonly because a local tunnel is missing or broken. | Environment |
generated_media_unwritable | The generated-media bucket write probe fails. | Storage/ops |
3. Voice and Presenter eligibility reason codes
| Reason code | Why it happens | Recommended surface |
|---|---|---|
voice_processing | An ElevenLabs Professional Voice Clone reports queued, fine-tuning, or delayed. | Wait/choose another |
voice_not_ready | The Professional Voice Clone reports draft, not started, or not verified. | Finish setup |
voice_training_failed | Every reported Professional Voice Clone training state is failed. | Repair/replace |
model_unsupported | Reserved in the reason-code contract; the current resolver does not emit it. | Declared only |
metadata_incomplete (voice) | ElevenLabs omits enough training/category data to establish eligibility, or does not identify a supported Instant Voice Clone. | Choose/retry |
voice_unavailable | The selected ElevenLabs voice lookup returns no matching voice. | Choose another |
look_unavailable | The selected HeyGen look no longer exists. | Choose another |
look_processing | HeyGen reports pending, processing, queued, training, or draft. | Wait/choose another |
look_failed | HeyGen returns a provider error or failed/error/rejected/deleted/disabled status. | Repair/replace |
metadata_incomplete (Presenter) | Status is not completed, or dimensions required for placement are absent/invalid. | Choose/retry |
engine_unsupported | The Presenter does not support the avatar_v engine required by Tours. | Choose another |
preview_unavailable | No preview image or video is available for Presenter positioning. | Choose another |
default_voice_unavailable | The HeyGen combined-narration strategy requires a default voice, but the Presenter has none. | Choose another |
4. Provider catalog and OpenRouter transport errors
| Code | Why it happens | Recommended surface |
|---|---|---|
ELEVENLABS_VOICES_FAILED | Voice catalog network error, timeout, or non-success HTTP response. | Reconnect/retry |
ELEVENLABS_VOICES_RESPONSE_INVALID | The catalog response is not the expected JSON shape. | Provider/ops |
ELEVENLABS_VOICES_PAGINATION_INVALID | Pagination token is missing/repeated or exceeds the 100-page safety limit per category. | Provider/ops |
HEYGEN_AVATARS_FAILED | Presenter catalog network error, timeout, or non-success HTTP response. | Reconnect/retry |
HEYGEN_AVATARS_RESPONSE_INVALID | Response shape is invalid, a required next token is absent/repeated, or pagination exceeds 1,000 pages. | Provider/ops |
OPENROUTER_CONFIGURATION_ERROR | The OpenRouter API key is absent. | Configuration |
OPENROUTER_AUTH_ERROR | OpenRouter returns HTTP 401. | Fix credential |
OPENROUTER_CREDITS_ERROR | OpenRouter returns HTTP 402 for insufficient provider credits. | Add provider credits |
OPENROUTER_RATE_LIMIT | OpenRouter returns HTTP 429. | Retryable |
OPENROUTER_BAD_REQUEST | OpenRouter returns HTTP 400 or another non-5xx status not mapped separately. | Request/model |
OPENROUTER_FORBIDDEN | OpenRouter returns HTTP 403. | Permission/policy |
OPENROUTER_TIMEOUT | OpenRouter returns HTTP 408. | Retryable |
OPENROUTER_PROVIDER_ERROR | OpenRouter returns HTTP 502 or another 5xx provider/platform error. | Retryable |
OPENROUTER_NETWORK_ERROR | The request throws before any HTTP response is received. | Retryable |
OPENROUTER_MALFORMED_RESPONSE | HTTP succeeds but JSON is invalid, chat JSON is malformed, or a video job id is absent. | Provider/ops |
OPENROUTER_MISSING_CONTENT | Chat content or the completed video output URL is missing. | Provider/ops |
OPENROUTER_VIDEO_JOB_FAILED | Video status becomes failed, cancelled, or expired. | Provider failure |
OPENROUTER_VIDEO_JOB_TIMEOUT | The job does not complete within the configured polling attempts. | Retryable |
5. Script planning errors (5 codes)
| Code | Why it happens | Stored safe message |
|---|---|---|
PROJECT_HAS_NO_INCLUDED_SCENES | Planning is called after all Scenes have been excluded/removed. | Script planning failed. |
SIGNED_IMAGE_URL_MISSING | A main Photo path cannot be converted to a signed provider URL. | Source photo URLs could not be signed for script planning. |
PROVIDER_RESPONSE_INVALID | The planner output lacks Scene timings, narration, automatic movement/Transition selections, or valid camera-directed movement; it may also contain malformed JSON. | The specific normalized planner message. |
SCRIPT_PLAN_UPLOAD_FAILED | The normalized plan cannot be written to generated-media storage. | Script plan upload failed. |
SCRIPT_PLAN_ASSET_CREATE_FAILED | Storage succeeds but the database asset row cannot be created. | Script plan asset could not be recorded. |
6. Narration and Presenter narration errors (26 codes)
| Code | Why it happens | Stored safe message family |
|---|---|---|
MISSING_SCRIPT_TEXT | The planned narration text is empty. | Voiceover generation failed. |
MISSING_NARRATION_VOICE_ID | The frozen narration plan has no voice id. | Voiceover generation failed. |
MISSING_ELEVENLABS_API_KEY | ElevenLabs is selected but its Profile key is absent at execution time. | ElevenLabs API key is not configured… |
MISSING_ELEVENLABS_VOICE_ID | The ElevenLabs provider is called without a selected voice id. | ElevenLabs voice id is not configured… |
MISSING_HEYGEN_API_KEY | HeyGen narration is selected but its Profile key is absent at execution time. | Voiceover generation failed. |
ELEVENLABS_TTS_FAILED | The ElevenLabs TTS request throws or returns non-success. | ElevenLabs voiceover generation failed. |
ELEVENLABS_TTS_RESPONSE_INVALID | The response lacks audio/alignment or contains empty audio. | ElevenLabs voiceover response was invalid. |
HEYGEN_TTS_FAILED | The HeyGen speech request fails or returns a provider failure. | Voiceover generation failed. |
HEYGEN_TTS_RESPONSE_INVALID | The speech response has no audio URL or otherwise violates the expected contract. | Voiceover generation failed. |
HEYGEN_AUDIO_DOWNLOAD_FAILED | The generated narration URL cannot be downloaded or returns empty audio. | HeyGen narration media could not be prepared. |
HEYGEN_TIMESTAMPS_MISSING | The HeyGen speech result omits word timestamps. | HeyGen narration timing could not be validated. |
HEYGEN_TIMESTAMPS_INVALID | Timestamps are malformed/non-monotonic or do not cover the narration script. | HeyGen narration timing could not be validated. |
HEYGEN_DURATION_MISMATCH | Timestamp coverage does not match the downloaded audio duration. | HeyGen narration timing could not be validated. |
HEYGEN_PRESENTER_CREATE_FAILED | Presenter creation fails or returns no video id. | HeyGen presenter narration generation failed. |
HEYGEN_PRESENTER_POLL_FAILED | Presenter status becomes failed or does not complete before polling times out. | HeyGen presenter narration generation failed. |
HEYGEN_PRESENTER_DOWNLOAD_FAILED | The completed Presenter video cannot be downloaded. | HeyGen narration media could not be prepared. |
HEYGEN_SUBTITLES_INVALID | Subtitles cannot be downloaded/parsed, are non-monotonic, mismatch audio, or do not cover the script. | HeyGen narration timing could not be validated. |
HEYGEN_AUDIO_EXTRACTION_FAILED | FFmpeg cannot extract narration audio from the Presenter video. | HeyGen narration media could not be prepared. |
VOICEOVER_AUDIO_UPLOAD_FAILED | Narration audio cannot be uploaded. | Voiceover assets could not be persisted. |
VOICEOVER_TRANSCRIPT_UPLOAD_FAILED | Narration timing JSON cannot be uploaded. | Voiceover assets could not be persisted. |
VOICEOVER_AUDIO_ASSET_CREATE_FAILED | The audio database asset row cannot be created. | Voiceover assets could not be persisted. |
VOICEOVER_TRANSCRIPT_ASSET_CREATE_FAILED | The transcript database asset row cannot be created. | Voiceover assets could not be persisted. |
PRESENTER_VIDEO_UPLOAD_FAILED | The combined HeyGen Presenter video cannot be uploaded. | Voiceover assets could not be persisted. |
PRESENTER_VIDEO_ASSET_CREATE_FAILED | Presenter configuration is missing or its database asset row cannot be created. | Voiceover assets could not be persisted. |
TRANSCRIPT_ALIGNMENT_FAILED | ElevenLabs alignment arrays disagree, are empty, or cannot map narration phrases to valid times. | Voiceover transcript timing could not be aligned. |
UNSUPPORTED_PHRASE_SEGMENTATION | Phrase mode is unsupported or wordsPerPhrase is not a positive integer. | Voiceover generation failed. |
| ElevenLabs provider credits exhausted Known classification gap | ElevenLabs accepts the configured key but rejects TTS because that provider account has insufficient credits or quota. The pipeline cannot reliably know this until it attempts generation; today the response is collapsed into ELEVENLABS_TTS_FAILED. | Name ElevenLabs, explain that its account needs credits, and do not retry automatically. |
| HeyGen provider credits exhausted Known classification gap | HeyGen accepts the configured key but rejects speech or Presenter creation because that provider account has insufficient credits or quota. The pipeline cannot reliably know this until it attempts generation; today it is collapsed into HEYGEN_TTS_FAILED, HEYGEN_PRESENTER_CREATE_FAILED, or HEYGEN_CREATE_FAILED. | Name HeyGen, explain that its account needs credits, and do not retry automatically. |
7. Transition timing errors (8 codes)
| Code | Why it happens | Stored safe message |
|---|---|---|
PROJECT_HAS_NO_INCLUDED_SCENES | Boundary detection is called without any included Scenes. | Generic render fallback. |
TRANSCRIPT_INVALID | Transcript is absent/empty, has no usable timed chunks, or a reused transcript asset is malformed/missing storage. | Scene transition timing could not be validated. |
PROVIDER_RESPONSE_INVALID | OpenRouter key/request/JSON fails; transitions are missing; count/order/Scene ids are wrong; or a boundary entry is malformed. | Scene boundary detection returned an invalid response. |
TRANSITION_TIMING_INVALID | Chunk ids are missing/out of order, time ranges are non-positive/too short, or stored durations do not map to current Scenes/transcript chunks. | Scene transition timing could not be validated. |
TRANSITIONS_UPLOAD_FAILED | Boundary JSON cannot be uploaded. | Generic render fallback. |
DURATIONS_UPLOAD_FAILED | Scene duration JSON cannot be uploaded. | Generic render fallback. |
TRANSITIONS_ASSET_CREATE_FAILED | The boundary database asset row cannot be created. | Generic render fallback. |
DURATIONS_ASSET_CREATE_FAILED | The duration database asset row cannot be created. | Generic render fallback. |
8. Scene creation errors (10 codes)
| Code | Why it happens | Stored safe message |
|---|---|---|
PROJECT_HAS_NO_INCLUDED_SCENES | Scene creation is called with no included Scenes. | Scene clip rendering failed. |
SCENE_DURATION_MISSING | A Scene lacks derived duration or its Transition handle plan. | Scene clip rendering failed. |
SOURCE_PHOTO_DOWNLOAD_FAILED | A main Photo cannot be downloaded for local FFmpeg movement rendering. | Scene clip rendering failed. |
SIGNED_SOURCE_PHOTO_URL_MISSING | A main Photo cannot be signed for provider image-to-video. | Scene clip rendering failed. |
SCENE_CLIP_RENDER_FAILED | FFmpeg movement rendering or provider-output normalization fails. | Scene clip rendering failed. |
SCENE_CLIP_PROVIDER_FAILED | The image-to-video provider/key is absent or OpenRouter rejects/fails/times out. | Scene clip rendering failed. |
SCENE_CLIP_PROVIDER_OUTPUT_IMPORT_FAILED | The provider output URL cannot be fetched or stored locally. | Scene clip rendering failed. |
SCENE_CLIP_DURATION_INVALID | The imported/normalized Scene video duration cannot be read or is shorter/different than required. | Scene clip duration could not be validated. |
SCENE_CLIP_UPLOAD_FAILED | The completed Scene video cannot be uploaded. | Scene clip upload failed. |
SCENE_CLIP_ASSET_CREATE_FAILED | The Scene video database asset row cannot be created. | Scene clip asset could not be recorded. |
9. Presenter overlay errors (13 codes)
| Code | Why it happens | Stored safe message family |
|---|---|---|
MISSING_HEYGEN_API_KEY | The Presenter stage reaches execution without a HeyGen key. | HeyGen API key is not configured… |
MISSING_HEYGEN_AVATAR_ID | The Presenter stage is called without a HeyGen avatar id. | HeyGen avatar id is not configured… |
MISSING_AVATAR_SOURCE | A reusable Presenter asset is missing, lacks storage metadata, or cannot be downloaded. | Avatar rendering failed. |
HEYGEN_CREATE_FAILED | HeyGen creation fails or returns no video id. | Avatar rendering failed. |
HEYGEN_POLL_FAILED | Status polling fails, reports provider failure, or times out. | Avatar rendering failed. |
HEYGEN_DOWNLOAD_FAILED | The completed HeyGen video cannot be downloaded. | Avatar rendering failed. |
AVATAR_ALPHA_ANALYSIS_FAILED | FFprobe/FFmpeg metadata or RGBA-frame analysis fails, no frames decode, or no non-transparent pixels are found. | Avatar rendering failed. |
AVATAR_LAYOUT_FAILED | Placement cannot be resolved from an empty alpha bounding box. | Avatar rendering failed. |
AVATAR_VIDEO_UPLOAD_FAILED | The processed Presenter video cannot be uploaded. | Avatar render assets could not be persisted. |
AVATAR_METADATA_UPLOAD_FAILED | Compositing metadata cannot be uploaded. | Avatar render assets could not be persisted. |
AVATAR_VIDEO_ASSET_CREATE_FAILED | The Presenter video database asset row cannot be created. | Avatar render assets could not be persisted. |
AVATAR_METADATA_ASSET_CREATE_FAILED | The Presenter metadata database asset row cannot be created. | Avatar render assets could not be persisted. |
FRAME_CHECK_FAILED | A sampled Presenter frame cannot be exported for visual safety analysis. | Avatar rendering failed. |
10. Final assembly errors (13 codes)
| Code | Why it happens | Stored safe message |
|---|---|---|
NO_SCENE_CLIPS | Final assembly is invoked without any Scene videos. | Final video rendering failed. |
SCENE_CLIP_STORAGE_MISSING | A Scene asset lacks its generated-media bucket/path. | Final video rendering failed. |
SCENE_CLIP_DOWNLOAD_FAILED | A stored Scene video cannot be downloaded. | Final video rendering failed. |
VOICEOVER_STORAGE_MISSING | A narration asset lacks its generated-media bucket/path. | Final video rendering failed. |
VOICEOVER_DOWNLOAD_FAILED | Stored narration audio cannot be downloaded. | Final video rendering failed. |
AVATAR_STORAGE_MISSING | A Presenter asset lacks its generated-media bucket/path. | Final video rendering failed. |
AVATAR_DOWNLOAD_FAILED | Stored Presenter video cannot be downloaded. | Final video rendering failed. |
CONCAT_FAILED | Transition assembly, Scene path mapping, FFmpeg concat, or joined-duration validation fails. | Scene clips could not be joined. |
MUX_FAILED | FFmpeg cannot combine joined video with narration/Presenter overlay. | Final video mux failed. |
JOINED_SCENES_UPLOAD_FAILED | The intermediate joined video cannot be uploaded. | Joined scene video upload failed. |
JOINED_SCENES_ASSET_CREATE_FAILED | The intermediate joined-video database asset row cannot be created. | Joined scene video asset could not be recorded. |
FINAL_VIDEO_UPLOAD_FAILED | The finished Listing Video cannot be uploaded. | Final video upload failed. |
FINAL_VIDEO_ASSET_CREATE_FAILED | The finished Listing Video database asset row cannot be created. | Final video asset could not be recorded. |
Raw transition and duration invariants folded into CONCAT_FAILED
- Scene path count differs from the Transition-handle plan count.
- A multi-Scene Transition join receives fewer than two Scene videos.
- A single-Scene join receives anything other than exactly one Scene video.
- The requested Transition effect is unsupported.
- Transition duration is zero/negative.
- A Scene target duration is not longer than its Transition.
- A required incoming Transition handle is missing or too short.
- A downloaded Scene path is missing.
- FFprobe cannot read a video duration.
- A normalized/joined duration is shorter than or differs from the canonical expected duration.
11. Orchestration, unknown exceptions, and notification failures
| Failure | Why it happens | Outcome |
|---|---|---|
| Render run not found | The Trigger payload references a run that cannot be reloaded under project/user scope. | Attempts to mark the run failed. |
| Profile cannot be resolved | The Listing/user has no usable platform Profile during worker execution. | Run marked failed. |
| Renderable context cannot load | The Listing/Scenes disappear or repository read fails after preflight. | Run marked failed. |
| Script/narration/Transition provider not configured | A dependency was not injected or environment configuration is incomplete. | Run marked failed. |
| Voiceover audio missing/unreachable for Presenter | Stored audio cannot load/sign or the URL is not reachable by HeyGen, often due to local tunnel configuration. | Run marked failed. |
| Presenter result/metadata missing | The child task returns no Presenter result or reusable metadata cannot be loaded for compositing. | Run marked failed. |
| Media child task failed | Any Scene or Presenter child reports ok: false, including child OOM/timeout/platform failure. | Parent records generic failure and can send email if it remains alive. |
| Final-video child task failed | The final child reports ok: false, including typed final errors or child platform failure. | Parent records generic failure and can send email if it remains alive. |
| Media batch returned no result | The batch-runner contract unexpectedly resolves undefined. | Generic safe fallback. |
| Final video saved, run completion failed | The final file exists, but the database cannot transition the run to completed. | Run marked failed; file may need ops recovery. |
| Unknown exception | Any untyped database, filesystem, FFmpeg, fetch, or programming error thrown inside the main generation try. | “Tour render failed before rendering could complete.” |
| Repository construction failure | The repository is created before the generation try; a throw here bypasses normal run failure persistence. | Trigger task fails; email is not guaranteed. |
| Parent Trigger.dev OOM/crash/max-duration | The process is killed before application catch/finalization code executes. | No application-level failure email can be guaranteed. |
| Child Trigger.dev OOM/crash/max-duration | A child process dies, but the parent survives and receives a failed child result. | Usually becomes generic media/final-child failure; email can still send. |
PLATFORM_RESEND_API_KEY missing | The failure-email task cannot construct the Resend client. | Email task retries, then parent logs notification failure. |
| Resend rejects failure email | Resend returns an API error, transport fails, or sender/recipient policy rejects the message. | Email task retries up to three attempts. |
| Failure-email task fails | The retryable email task returns ok: false. | Parent logs it but preserves the original render failure. |
| Recipient/project missing | The email task reload guard cannot find the failed run/Listing/user email, or the run is no longer failed. | Email is safely skipped. |
Recommended customer disclosure policy
| Failure class | Customer should see | Keep internal |
|---|---|---|
| Customer-fixable preflight | Specific cause + saved-work assurance + one direct action, ideally deep-linked. | Internal code and ids. |
| Credential/provider eligibility | Name ElevenLabs or HeyGen only when reconnecting, waiting, repairing, or selecting another item will help. | Provider payloads and account identifiers. |
| Provider account credits exhausted | “Your ElevenLabs/HeyGen account does not have enough credits to finish this Listing Video. Add credits with that provider, then try again.” Keep the Listing link and saved-work assurance. | Raw provider response, provider account id, balance, quota, and billing metadata. |
| Transient provider/platform | “We couldn’t create your Listing Video. Your Listing is saved. Try again.” | HTTP status, model, provider response, retry metadata. |
| Internal media/persistence invariant | Generic retry; after repeated failure, offer a help path with a safe support reference. | FFmpeg text, storage paths, asset/run ids, stack traces. |
| Trigger.dev parent process death | Best-effort monitoring should detect stale runs; ordinary application code cannot promise an immediate email. | Machine/OOM diagnostics. |