{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "vclaw error response",
  "description": "Stable error-code catalog for vclaw CLI JSON output. The TS source-of-truth is src/video/errors.ts ALL_ERROR_CODES.",
  "type": "object",
  "required": ["code", "message"],
  "properties": {
    "code": { "type": "string" },
    "message": { "type": "string" },
    "details": { "type": "object", "additionalProperties": true }
  },
  "codes": [
    { "code": "invalid_slug", "exitCode": 1, "description": "Slug is missing or fails isProjectSlug validation." },
    { "code": "project_not_found", "exitCode": 1, "description": "Referenced project slug has no workspace on disk." },
    { "code": "missing_required_flag", "exitCode": 1, "description": "A flag required by the subcommand was not provided." },
    { "code": "invalid_flag_value", "exitCode": 1, "description": "A flag was provided but its value is out of range, malformed, or otherwise invalid." },
    { "code": "unknown_subcommand", "exitCode": 1, "description": "The subcommand is not in the dispatch table." },
    { "code": "invalid_mode", "exitCode": 1, "description": "--mode value is not 'storyboard' or 'director'." },
    { "code": "invalid_aspect_ratio", "exitCode": 1, "description": "Aspect ratio is not 16:9 / 9:16 / 1:1." },
    { "code": "image_not_found", "exitCode": 1, "description": "Referenced image file (asset or reference) is not on disk." },
    { "code": "asset_not_found", "exitCode": 1, "description": "Referenced asset (image/video/audio) is not on disk." },
    { "code": "template_not_found", "exitCode": 1, "description": "Referenced template name is not registered." },
    { "code": "character_not_found", "exitCode": 1, "description": "Referenced character name is not in the project's characters/." },
    { "code": "character_identity_conflict", "exitCode": 1, "description": "A character of this name already exists with a different description; reusing it would render someone other than the character described. Pick a distinct name or pass --reuse-existing." },
    { "code": "duplicate_project", "exitCode": 1, "description": "vclaw video init on a slug whose workspace already exists." },
    { "code": "directory_not_writable", "exitCode": 1, "description": "Workspace root is not writable." },
    { "code": "invalid_role", "exitCode": 1, "description": "Reference (--ref or --gb-ref) uses a role that's not valid for the sheet's --type." },
    { "code": "invalid_audio_format", "exitCode": 1, "description": "Provided audio file format/container is not supported by the assemble pipeline." },
    { "code": "invalid_video_format", "exitCode": 1, "description": "Provided video file format/container is not supported by the assemble pipeline." },
    { "code": "unsupported_codec", "exitCode": 1, "description": "Audio/video stream uses a codec the assemble pipeline cannot process." },
    { "code": "motion_sheet_missing", "exitCode": 1, "description": "No artifacts/motion-sheet.json on the project; create it via mograph-sheet --from-json --write." },
    { "code": "motion_sheet_locked", "exitCode": 1, "description": "The motion sheet is locked; overwriting re-styles every future clip and needs --force with explicit approval." },
    { "code": "motion_sheet_invalid", "exitCode": 1, "description": "Motion sheet failed validation (style-lock budget/layout guard, audio-ban tail, unknown family, undescribed locked stage)." },
    { "code": "motion_pack_missing", "exitCode": 1, "description": "No artifacts/motion-pack.json on the project; seed one via mograph-pack --init-from or author it." },
    { "code": "motion_pack_exists", "exitCode": 1, "description": "A motion pack already exists; --init-from refuses to overwrite without --force." },
    { "code": "motion_pack_invalid", "exitCode": 1, "description": "Motion pack failed the anti-drift lint (mograph-pack --check); fix the listed errors before rendering." },
    { "code": "mograph_plan_invalid", "exitCode": 1, "description": "Render plan has blockers (empty scope, missing sheet reference image, or reference budget exceeded)." },
    { "code": "stock_auth_failed", "exitCode": 1, "description": "Stock provider credentials are missing or rejected; configure the provider-specific env var, such as PEXELS_API_KEY." },
    { "code": "stock_media_invalid", "exitCode": 1, "description": "Selected stock media/rendition is not a valid downloadable video asset for import." },
    { "code": "publish_metadata_missing", "exitCode": 1, "description": "Publish packaging requires explicit local publish metadata with title, visibility, and synthetic-media disclosure." },
    { "code": "provider_unreachable", "exitCode": 2, "description": "Provider HTTP / native transport returned a non-recoverable error." },
    { "code": "stock_provider_unavailable", "exitCode": 2, "description": "Stock provider search or API response was unavailable, malformed, timed out, or otherwise unusable." },
    { "code": "stock_rate_limited", "exitCode": 2, "description": "Stock provider rate limit was reached." },
    { "code": "stock_download_failed", "exitCode": 2, "description": "Stock rendition download failed or timed out before a valid asset could be written." },
    { "code": "logo_fetch_failed", "exitCode": 2, "description": "No logo source (Clearbit/SimpleIcons/favicon) returned a usable mark for any requested brand." },
    { "code": "adapter_command_failed", "exitCode": 2, "description": "User-provided ..._ADAPTER command exited non-zero." },
    { "code": "env_var_missing", "exitCode": 2, "description": "Required env var (e.g. USEAPI_API_TOKEN) is not set for the chosen route." },
    { "code": "native_transport_failed", "exitCode": 2, "description": "native-veo / native-seedance / native-runway hit an internal error." },
    { "code": "schema_validation_failed", "exitCode": 2, "description": "Artifact failed its JSON-Schema validation." },
    { "code": "workspace_corrupt", "exitCode": 2, "description": "projects/<slug>/ has missing or malformed canonical files." },
    { "code": "unexpected_internal_error", "exitCode": 2, "description": "Catch-all for unanticipated exceptions; always a bug." },
    { "code": "tts_failed", "exitCode": 2, "description": "Text-to-speech narration generation failed (provider error or invalid output)." },
    { "code": "music_gen_failed", "exitCode": 2, "description": "Background music generation failed (provider error or invalid output)." },
    { "code": "soundtrack_no_backend", "exitCode": 2, "description": "No music backend is available/configured for soundtrack generation (set credentials for at least one, e.g. KIE_API_KEY)." },
    { "code": "pdf_parse_failed", "exitCode": 2, "description": "PDF slide extraction failed to parse or render the source document." },
    { "code": "ffmpeg_failed", "exitCode": 2, "description": "An FFmpeg subprocess exited non-zero during assemble." },
    { "code": "audio_sync_drift", "exitCode": 2, "description": "Narration/music audio drifted out of sync with video beyond tolerance during stitch." },
    { "code": "assemble_missing_scene_clips", "exitCode": 3, "description": "assemble --from-clips found storyboard scene(s) with no rendered clip on a real run; render them or pass --allow-missing-scenes." },
    { "code": "storyboard_approval_required", "exitCode": 3, "description": "Director-mode execute requires storyboard.md approval." },
    { "code": "storyboard_review_stale", "exitCode": 3, "description": "Director storyboard review state is 'stale'; re-run storyboard-review." },
    { "code": "execution_blocked_by_readiness", "exitCode": 3, "description": "readiness check reported blockers; resolve before plan/execute." },
    { "code": "spend_confirmation_required", "exitCode": 3, "description": "A paid-provider command was run directly without --dry-run; pass --confirm-spend to authorize the spend." },
    { "code": "flow_identity_unregistered", "exitCode": 3, "description": "A veo-useapi scene names cast members but no registered Flow Character resolved, so faces would be reinvented per shot; run `vclaw video flow-register-characters` first." },
    { "code": "scene_selection_stale", "exitCode": 3, "description": "A scene is marked selected but its output file is missing, so the resumable driver would skip it instead of re-rendering; clear it with `vclaw video reroll-scene --scene <i> --void`." },
    { "code": "cinema_evidence_required", "exitCode": 3, "description": "Cinema compile/preflight found unresolved character-sheet, recognition, rights, voice or dialogue-authorship gates; no shot manifests or provider work were created." },
    { "code": "stock_license_missing", "exitCode": 3, "description": "Stock media is missing complete source/license provenance required for import, packaging, or publish." }
  ]
}
