{"record":{"id":"121fed1e5cf5e584","repo":"bytedance/deer-flow","slug":"failed-to-load-demo-thread-threadid","errorCode":null,"errorMessage":"Failed to load demo thread ${threadId}","messagePattern":"Failed to load demo thread (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"frontend/src/core/threads/static-demo.ts","lineNumber":178,"sourceCode":"    return sortOrder === \"asc\" ? aValue - bValue : bValue - aValue;\n  });\n\n  const offset = Math.max(0, Math.floor(params.offset ?? 0));\n  const limit =\n    typeof params.limit === \"number\"\n      ? Math.max(0, Math.floor(params.limit))\n      : sortedThreads.length;\n  return sortedThreads.slice(offset, offset + limit);\n}\n\nexport async function loadStaticDemoThread(\n  threadId: string,\n): Promise<AgentThread> {\n  const response = await globalThis.fetch(\n    `/demo/threads/${encodeURIComponent(threadId)}/thread.json`,\n  );\n  if (!response.ok) {\n    throw new Error(`Failed to load demo thread ${threadId}`);\n  }\n  const thread = (await response.json()) as AgentThread;\n  return {\n    ...thread,\n    thread_id: threadId,\n    updated_at: thread.updated_at ?? thread.created_at,\n  };\n}\n\nexport function staticDemoThreadState(\n  thread: AgentThread,\n): ThreadState<AgentThreadState> {\n  return {\n    values: thread.values,\n    next: [],\n    checkpoint: {\n      thread_id: thread.thread_id,\n      checkpoint_ns: \"\",","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/frontend/src/core/threads/static-demo.ts#L160-L196","documentation":"Static-demo loader: fetches /demo/threads/{threadId}/thread.json (a bundled fixture, not a gateway call) and throws when the response is not ok. The loaded fixture's thread_id is forced to the requested id and updated_at defaults to created_at.","triggerScenarios":"Requesting a demo thread id with no corresponding public/demo data file (404), the static demo mode enabled but the /demo route not served (dev server misconfig, missing copy of demo assets), or a moved/renamed thread.json in the demo dataset.","commonSituations":"Deep-linking to a demo thread URL after the fixture set changed; running a frontend build where /demo assets were excluded; nginx not serving the demo directory in the docker stack.","solutions":["Open /demo/threads/<id>/thread.json directly in the browser to confirm the 404/serve failure.","Verify the id exists in the demo thread index (the data used by the thread list in static-demo.ts).","Ensure the static demo assets directory is deployed/served (check nginx config or Next public path).","If the fixture was renamed, update the id in links/bookmarks or restore the file."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const exists = demoThreadIds.includes(threadId); // from the same static index that powers the list\nif (!exists) { router.replace('/demo'); }","typeGuard":"function isKnownDemoThread(threadId: string): boolean {\n  return staticDemoIndex().some((t) => t.thread_id === threadId);\n}","tryCatchPattern":"try { thread = await loadStaticDemoThread(id); } catch { renderThreadNotFound(); return; }","preventionTips":["Generate the demo thread list and thread.json files from one source so ids can't drift.","Smoke-test /demo routes in CI builds.","Deep links into demo threads should degrade to the demo index, not a crash."],"tags":["demo","static-assets","frontend","threads"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}