{"record":{"id":"b6e64300117cc643","repo":"can1357/oh-my-pi","slug":"browser-download-stalled-while-writing-destinati","errorCode":null,"errorMessage":"Browser download stalled while writing ${destination}","messagePattern":"Browser download stalled while writing (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/utils/src/browsers.ts","lineNumber":357,"sourceCode":"\tdestination: string,\n\tonProgress: ((progress: BrowserDownloadProgress) => void) | undefined,\n): Promise<void> {\n\tconst response = await fetch(url);\n\tif (!response.ok || !response.body) {\n\t\tthrow new Error(`Browser download failed (${response.status} ${response.statusText}) from ${url}`);\n\t}\n\tconst totalBytes = Number(response.headers.get(\"content-length\") ?? 0);\n\tconst file = await fsp.open(destination, \"wx\");\n\tlet downloadedBytes = 0;\n\ttry {\n\t\tconst reader = response.body.getReader();\n\t\tfor (;;) {\n\t\t\tconst chunk = await reader.read();\n\t\t\tif (chunk.done) break;\n\t\t\tlet offset = 0;\n\t\t\twhile (offset < chunk.value.byteLength) {\n\t\t\t\tconst write = await file.write(chunk.value, offset, chunk.value.byteLength - offset, null);\n\t\t\t\tif (write.bytesWritten === 0) throw new Error(`Browser download stalled while writing ${destination}`);\n\t\t\t\toffset += write.bytesWritten;\n\t\t\t}\n\t\t\tdownloadedBytes += chunk.value.byteLength;\n\t\t\tonProgress?.({ downloadedBytes, totalBytes });\n\t\t}\n\t} finally {\n\t\tawait file.close();\n\t}\n}\n","sourceCodeStart":339,"sourceCodeEnd":367,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/browsers.ts#L339-L367","documentation":"Thrown by downloadArchive in packages/utils/src/browsers.ts while streaming a browser archive to disk. After each chunk write, the returned write result reports bytesWritten; a value of 0 means the filesystem accepted none of the data, so the download cannot make progress and is aborted instead of looping forever.","triggerScenarios":"Calling install() (which calls downloadArchive) when FileHandle.write() repeatedly reports bytesWritten === 0 for a chunk — typically a full disk, an I/O error on the destination file, or the file handle becoming unwritable mid-write.","commonSituations":"Disk quota exceeded or volume full while installing a browser (Chromium/Firefox) into the cache dir; network filesystem or external drive dropped mid-download; corrupted destination file handle after system sleep/hibernation.","solutions":["Free disk space (or check quota) on the volume holding the destination and retry the install.","Delete any partial/stale file at `destination` and retry so a fresh handle is created.","Retry the install; transient I/O stalls (e.g. sleeping external drive) often clear.","If on a network mount, download to a local temp dir and move the result."],"exampleFix":"// before\nawait install({ browser: 'chromium' }); // throws when disk full\n// after\nimport { statfsSync } from 'node:fs';\nconst space = statfsSync(destinationDir);\nif (space.bavail * space.bsize < 500 * 1024 * 1024) {\n  throw new Error('Not enough disk space for browser download');\n}\nawait install({ browser: 'chromium' });","handlingStrategy":"retry","validationCode":"import { statfsSync } from 'node:fs';\nconst s = statfsSync(destinationDir);\nif (s.bavail * s.bsize < 500 * 1024 * 1024) throw new Error('Insufficient disk space for browser download');","typeGuard":null,"tryCatchPattern":"try {\n  await install({ browser: 'chromium' });\n} catch (err) {\n  if (err.message.includes('download stalled')) {\n    // check disk space / remove partial file, then retry once\n  }\n  throw err;\n}","preventionTips":["Ensure several hundred MB free on the destination volume before installing browsers.","Install to a local (non-network) filesystem path.","Clear stale partial downloads from the browser cache directory periodically."],"tags":["filesystem","download","disk-full","io"],"backgroundTag":"disk-full-write-stalled","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}