{"record":{"id":"b53b106c2482b176","repo":"bytedance/deer-flow","slug":"failed-to-load-workspace-changes","errorCode":null,"errorMessage":"Failed to load workspace changes.","messagePattern":"Failed to load workspace changes\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src/core/workspace-changes/api.ts","lineNumber":30,"sourceCode":"  runId: string;\n  includeFiles?: boolean;\n  includeDiff?: boolean;\n}): Promise<WorkspaceChangesResponse> {\n  const query = new URLSearchParams({\n    include_files: includeFiles ? \"true\" : \"false\",\n    include_diff: includeDiff ? \"true\" : \"false\",\n  });\n  const response = await fetch(\n    `${getBackendBaseURL()}/api/threads/${encodeURIComponent(\n      threadId,\n    )}/runs/${encodeURIComponent(runId)}/workspace-changes?${query}`,\n  );\n\n  if (!response.ok) {\n    const error = await response\n      .json()\n      .catch(() => ({ detail: \"Failed to load workspace changes.\" }));\n    throw new Error(error.detail ?? \"Failed to load workspace changes.\");\n  }\n\n  return response.json();\n}\n","sourceCodeStart":12,"sourceCodeEnd":35,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/frontend/src/core/workspace-changes/api.ts#L12-L35","documentation":"fetchWorkspaceChanges GETs /api/threads/{threadId}/runs/{runId}/workspace-changes (with include_diff flag) and throws when the response is not ok, using the body's detail or the fallback text when the body is not JSON.","triggerScenarios":"Requesting workspace changes for a run id the gateway no longer retains (404 after run-state pruning), a thread/run mismatch (400/404), expired session (401), or a 500 when diff generation fails server-side.","commonSituations":"Opening the workspace-changes panel on an old run after gateway restart cleared in-memory run state; session expiry in a long-lived tab; very large diffs timing out.","solutions":["Check the workspace-changes request status in the Network tab.","404/410: the run's change data is gone — re-run the agent or reload the thread; the panel can show an empty state.","401: re-auth and refetch.","5xx/timeout: retry with include_diff=false first (cheaper), then inspect gateway logs for the diff builder."],"exampleFix":"// before: full diff always requested\nconst changes = await fetchWorkspaceChanges(threadId, runId, true);\n\n// after: fetch metadata first, diff on demand\nconst meta = await fetchWorkspaceChanges(threadId, runId, false);\nconst withDiff = selectedFile ? await fetchWorkspaceChanges(threadId, runId, true) : meta;","handlingStrategy":"fallback","validationCode":"if (!runId) { /* no run selected: don't fetch */ }","typeGuard":"function hasRunRef(threadId?: string, runId?: string): boolean { return Boolean(threadId && runId); }","tryCatchPattern":"try { const changes = await fetchWorkspaceChanges(threadId, runId, includeDiff); } catch (e) { if (isGone(e) || isNotFound(e)) { setPanelEmptyState(); } else { toast('Could not load workspace changes'); retryOnce(); } }","preventionTips":["Fetch metadata (include_diff=false) first; request diffs lazily per file.","Handle run-pruned (404/410) as an empty panel, not an error.","Gate the fetch on a live run id from the thread's latest state."],"tags":["api","workspace-changes","runs","network","frontend"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}