{"record":{"id":"8c350d8dcc5c5508","repo":"alyssaxuu/screenity","slug":"drive-resumable-upload-finished-without-final-resp","errorCode":null,"errorMessage":"Drive resumable upload finished without final response","messagePattern":"Drive resumable upload finished without final response","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/pages/Background/drive/handleSaveToDrive.js","lineNumber":270,"sourceCode":"    }\n    // Drive accepted none of the chunk. Resending the same range is correct,\n    // but bound it so a persistently stalled upload fails instead of looping.\n    stalledRounds += 1;\n    if (stalledRounds >= MAX_STALL_ROUNDS) {\n      throw new Error(\n        `Drive resumable upload made no progress at offset ${offset}`\n      );\n    }\n    const stallDelay = Math.min(1000 * Math.pow(2, stalledRounds - 1), 15000);\n    diagEvent(\"drive-chunk-stall\", {\n      offset,\n      round: stalledRounds,\n      delayMs: stallDelay,\n    });\n    await new Promise((r) => setTimeout(r, stallDelay));\n  }\n\n  throw new Error(\"Drive resumable upload finished without final response\");\n};\n\nconst isAuthError = (err) => {\n  const msg = String(err?.message || err || \"\");\n  return / 401\\b/.test(msg) || /401 /.test(msg);\n};\n\n// Map a Drive failure to a stable code the editor turns into a specific\n// message. The reason strings come from Drive's 403/400 JSON body, which we\n// already carry in the thrown message but used to discard client-side.\nconst classifyDriveError = (err) => {\n  const msg = String(err?.message || err || \"\");\n  // storageQuotaExceeded is the account-full reason. Drive also returns\n  // \"Quota exceeded for quota metric ...\" for API rate limits, which is\n  // transient, so don't match that loosely or a rate limit tells the user\n  // their Drive is full.\n  if (/storageQuotaExceeded/i.test(msg)) {\n    return \"drive-quota\";","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/alyssaxuu/screenity/blob/512606387b8d07dda5e63bb428bd063f0a2a3ed0/src/pages/Background/drive/handleSaveToDrive.js#L252-L288","documentation":"The upload loop completed all chunks (or stopped after stall/abort handling) but never received Drive's terminating 200/201 response containing the file resource, so the uploaded file's ID is unknown. Thrown as the final post-loop guard in uploadResumable.","triggerScenarios":"Thrown at src/pages/Background/drive/handleSaveToDrive.js:270 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Query the resumable session with PUT Content-Range: bytes */size to elicit the final 201 response and file ID","If the session is gone (410), list the Screenity folder for the sanitized filename to recover the ID","Retry finalization with backoff; only re-upload if the session is unrecoverable"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"512606387b8d07dda5e63bb428bd063f0a2a3ed0","analyzedAt":"2026-09-02T20:59:09.419Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}