{"record":{"id":"66e3a8d0e6f5b4a5","repo":"astral-sh/ruff","slug":"failed-to-save-playground-response-status-66e3a8","errorCode":null,"errorMessage":"Failed to save playground: ${response.status}","messagePattern":"Failed to save playground: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"playground/ty/src/Editor/api.ts","lineNumber":34,"sourceCode":"\n  if (!response.ok) {\n    throw new Error(`Failed to fetch playground ${id}: ${response.status}`);\n  }\n\n  return await response.json();\n}\n\n/**\n * Save a playground and return its ID.\n */\nexport async function savePlayground(playground: Playground): Promise<string> {\n  const response = await fetch(API_URL, {\n    method: \"POST\",\n    body: JSON.stringify(playground),\n  });\n\n  if (!response.ok) {\n    throw new Error(`Failed to save playground: ${response.status}`);\n  }\n\n  return await response.text();\n}\n","sourceCodeStart":16,"sourceCodeEnd":39,"githubUrl":"https://github.com/astral-sh/ruff/blob/672bb4edf04c84f8b0753346359daee4057158f2/playground/ty/src/Editor/api.ts#L16-L39","documentation":"Thrown by the ty playground's savePlayground when the POST of the multi-file project (files map plus current file name) to the share API returns a non-2xx status. The worker was reached but refused or failed to store the project.","triggerScenarios":"POST to API_URL with the JSON-serialized playground returning 5xx (worker/storage failure) or 4xx (rejected payload).","commonSituations":"Sharing a ty playground during a worker outage; very large multi-file payloads; local dev where the worker runs but the save route misbehaves.","solutions":["Inspect response.status in devtools to tell payload problems (4xx) from server problems (5xx)","Retry once after a short delay for transient 5xx errors","In local dev, restart `wrangler dev` so the current save route is served on localhost:8787","Keep a local copy of the files; re-save after the worker recovers"],"exampleFix":"// before\nconst id = await savePlayground(playground);\n\n// after\nlet id: string | null = null;\ntry {\n  id = await savePlayground(playground);\n} catch (error) {\n  console.error((error as Error).message);\n  // keep working locally; user can retry sharing\n}","handlingStrategy":"try-catch","validationCode":"const payload = JSON.stringify(playground);\nif (!playground.current || !(playground.current in playground.files)) {\n  throw new RangeError('Playground current file must exist in files');\n}","typeGuard":"function isSavePayload(p: Playground): boolean {\n  return Object.keys(p.files).length > 0 && p.current in p.files;\n}","tryCatchPattern":"try {\n  return await savePlayground(playground);\n} catch (error) {\n  console.error(`Save failed: ${(error as Error).message}`);\n  return null;\n}","preventionTips":["Persist the multi-file project locally before saving to the API","Ensure the current file always exists in the files map before sharing","Offer an explicit retry when a save fails"],"tags":["network","http","playground","typescript"],"backgroundTag":null,"analyzedSha":"672bb4edf04c84f8b0753346359daee4057158f2","analyzedAt":"2026-08-16T08:54:05.464Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}