{"record":{"id":"45fdd3c7ae6ba689","repo":"abi/screenshot-to-code","slug":"data-detail-request-failed","errorCode":null,"errorMessage":"data.detail || \"Request failed\"","messagePattern":"data\\.detail \\|\\| \"Request failed\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/components/evals/EvalSessionsPage.tsx","lineNumber":325,"sourceCode":"      toast.error(\"Failed to activate session.\");\n    }\n  };\n\n  const handleCreate = async () => {\n    if (!newSessionSet) return;\n    setIsCreating(true);\n    try {\n      const response = await fetch(`${HTTP_BACKEND_URL}/eval-sessions`, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({\n          eval_set: newSessionSet,\n          name: newSessionName.trim() || null,\n        }),\n      });\n      if (!response.ok) {\n        const data = await response.json();\n        throw new Error(data.detail || \"Request failed\");\n      }\n      const created: EvalSession = await response.json();\n      setNewSessionName(\"\");\n      toast.success(`Session \"${created.name}\" started.`);\n      await fetchSessions();\n      loadMatrix(created.session_id);\n    } catch (error) {\n      console.error(\"Error creating session\", error);\n      toast.error(String(error));\n    } finally {\n      setIsCreating(false);\n    }\n  };\n\n  const openRun = (runId: string) => {\n    navigate(`/evals/agent-runs?run=${encodeURIComponent(runId)}`);\n  };\n","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/abi/screenshot-to-code/blob/d026163f586dfa8c5c10d28c36edd59a9d3b0e88/frontend/src/components/evals/EvalSessionsPage.tsx#L307-L343","documentation":"Client-side fallback error thrown by the eval sessions UI when POST ${HTTP_BACKEND_URL}/eval-sessions returns a non-2xx status. It surfaces whatever the FastAPI backend put in the response body's `detail` field, or the generic string 'Request failed' when the body has no detail (e.g. empty body or non-JSON error page). The error is then shown via toast.error(String(error)), so the user sees 'Error: <detail>'.","triggerScenarios":"Clicking 'start session' in EvalSessionsPage with a set name that fails server-side validation (invalid characters, unknown set), backend returning 422/500, or the backend being unreachable/proxy returning an HTML error page so response.json() itself rejects and jumps to the generic catch.","commonSituations":"Backend not running on the configured HTTP port, CORS/proxy intercepting the request, creating a session for an eval set that was deleted on disk, or FastAPI raising HTTPException with a detail message the UI just echoes.","solutions":["Open browser devtools Network tab and inspect the actual response status and body to see the backend's detail message.","Verify the backend is running and HTTP_BACKEND_URL points at it (default port 7001).","If the detail mentions the set name, fix or create the eval set before starting a session.","Make response parsing defensive: check content-type before .json() so an HTML error page does not mask the real status code."],"exampleFix":"// before\nif (!response.ok) {\n  const data = await response.json();\n  throw new Error(data.detail || \"Request failed\");\n}\n\n// after\nif (!response.ok) {\n  let detail = `Request failed (${response.status})`;\n  try {\n    const data = await response.json();\n    if (data?.detail) detail = String(data.detail);\n  } catch { /* non-JSON body */ }\n  throw new Error(detail);\n}","handlingStrategy":"try-catch","validationCode":"const ok = typeof newSessionSet === \"string\" && /^[A-Za-z0-9][A-Za-z0-9._ -]*$/.test(newSessionSet);\nif (!ok) { toast.error(\"Invalid set name\"); return; }","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(url, opts);\n  if (!res.ok) {\n    const body = await res.json().catch(() => null);\n    throw new Error(body?.detail ?? `Request failed (${res.status})`);\n  }\n  return await res.json();\n} catch (e) {\n  toast.error(e instanceof Error ? e.message : String(e));\n} finally {\n  setIsCreating(false);\n}","preventionTips":["Always handle non-2xx before parsing the body, and guard .json() with .catch for non-JSON error pages.","Include the HTTP status in fallback messages so failures are diagnosable from the toast alone.","Validate the set name client-side with the same pattern the backend enforces."],"tags":["http","frontend","error-handling","evals"],"backgroundTag":null,"analyzedSha":"d026163f586dfa8c5c10d28c36edd59a9d3b0e88","analyzedAt":"2026-08-14T22:02:06.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}