{"record":{"id":"a67c4ff589748658","repo":"invoke-ai/InvokeAI","slug":"video-workflow-not-found","errorCode":null,"errorMessage":"Video workflow not found","messagePattern":"Video workflow not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"info","filePath":"invokeai/app/api/routers/videos.py","lineNumber":529,"sourceCode":"    except Exception:\n        raise HTTPException(status_code=404)\n\n\n@videos_router.get(\n    \"/i/{video_name}/workflow\", operation_id=\"get_video_workflow\", response_model=WorkflowAndGraphResponse\n)\ndef get_video_workflow(\n    current_user: CurrentUserOrDefault,\n    video_name: str = PathParam(description=\"The name of video whose workflow to get\"),\n) -> WorkflowAndGraphResponse:\n    \"\"\"Gets the workflow and graph saved with a generated video (mirrors the image route).\"\"\"\n    _assert_video_read_access(video_name, current_user)\n    try:\n        workflow = ApiDependencies.invoker.services.videos.get_workflow(video_name)\n        graph = ApiDependencies.invoker.services.videos.get_graph(video_name)\n        return WorkflowAndGraphResponse(workflow=workflow, graph=graph)\n    except Exception:\n        raise HTTPException(status_code=404)\n\n\ndef _parse_range_header(range_header: str, file_size: int) -> Optional[tuple[int, int]]:\n    \"\"\"Parses an HTTP Range header of the form `bytes=START-END`. Returns inclusive (start, end)\n    byte offsets, or None if the header is malformed or unsatisfiable.\"\"\"\n    match = re.match(r\"^bytes=(\\d*)-(\\d*)$\", range_header.strip())\n    if match is None:\n        return None\n    if file_size <= 0:\n        # No byte range is satisfiable against an empty file (a suffix range would\n        # otherwise \"satisfy\" with the invalid pair (0, -1)).\n        return None\n    start_str, end_str = match.group(1), match.group(2)\n    if start_str == \"\" and end_str == \"\":\n        return None\n    if start_str == \"\":\n        # suffix range: last N bytes\n        try:","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/api/routers/videos.py#L511-L547","documentation":"Raised by get_video_workflow (GET videos/i/{video_name}/workflow) as HTTP 404 when fetching the workflow or graph associated with a video throws any exception. Videos created outside a workflow (e.g. plain uploads) or with unrecorded source workflow data will not have this association, so 404 is an expected outcome, not necessarily a malfunction.","triggerScenarios":"Requesting the workflow of a video that was never generated from a workflow; the source workflow/graph record was deleted or pruned; video_name does not exist; DB read failure.","commonSituations":"UI showing 'View workflow' for videos whose workflow was since deleted; videos copied between installs without workflow records; older videos predating workflow capture.","solutions":["Handle 404 as 'no workflow attached' and hide/disable the workflow-view affordance in the UI.","Verify the video exists first (GET videos/i/{video_name}) to separate 'no workflow' from 'no video'.","If workflow data is expected, check the workflows records in the database for deletion or migration gaps.","Check server logs if the video and workflow both exist yet the endpoint still 404s."],"exampleFix":"// before\nconst { workflow } = await api.getVideoWorkflow(name); // throws when absent\n// after\ntry {\n  const { workflow } = await api.getVideoWorkflow(name);\n} catch (e) {\n  if (e.status === 404) return null; // video has no source workflow\n  throw e;\n}","handlingStrategy":"fallback","validationCode":"const exists = await api.getVideoDto(name).then(() => true, () => false);\nif (!exists) return null; // video gone, workflow endpoint will 404","typeGuard":null,"tryCatchPattern":"try {\n  return await api.getVideoWorkflow(name);\n} catch (e) {\n  if (e.response?.status === 404) return null; // no source workflow attached\n  throw e;\n}","preventionTips":["Only show 'open workflow' UI when the video was generated from a workflow.","Treat 404 as the normal 'no workflow' case, not an error state.","Note: the endpoint 404s without a detail body — match on status code only."],"tags":["http-404","workflow","video","rest-api"],"backgroundTag":"resource-not-found-404","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}