{"record":{"id":"4afdfaaaa8a04137","repo":"garrytan/gstack","slug":"failed-to-decode-blob-data","errorCode":null,"errorMessage":"Failed to decode blob data","messagePattern":"Failed to decode blob data","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/write-commands.ts","lineNumber":1207,"sourceCode":"            const resp = await fetch(blobUrl);\n            const blob = await resp.blob();\n            if (blob.size > 100 * 1024 * 1024) return 'ERROR:TOO_LARGE';\n            return new Promise<string>((resolve, reject) => {\n              const reader = new FileReader();\n              reader.onloadend = () => resolve(reader.result as string);\n              reader.onerror = () => reject('Failed to read blob');\n              reader.readAsDataURL(blob);\n            });\n          } catch (err: any) {\n            return `ERROR:EXPIRED:${err?.message || 'unknown'}`;\n          }\n        }, url);\n\n        if (dataUrl === 'ERROR:TOO_LARGE') throw new Error('Blob too large (>100MB). Use a different approach.');\n        if (dataUrl.startsWith('ERROR:EXPIRED')) throw new Error(`Blob URL expired or inaccessible: ${dataUrl.slice('ERROR:EXPIRED:'.length)}`);\n\n        const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);\n        if (!match) throw new Error('Failed to decode blob data');\n        contentType = match[1];\n        buffer = Buffer.from(match[2], 'base64');\n      } else if (useNavigate) {\n        // Strategy 2: Navigate to URL and capture browser-triggered download.\n        // Handles URLs that trigger file downloads via redirects,\n        // Content-Disposition headers, or anti-bot CDN chains where\n        // page.request.fetch() can't follow the auth/redirect chain.\n        await validateNavigationUrl(url);\n        const downloadPromise = page.waitForEvent('download', { timeout: 60000 });\n        // Use goto with 'commit' wait — the page may redirect to trigger\n        // the download, so 'domcontentloaded' may never fire.\n        page.goto(url, { waitUntil: 'commit', timeout: 30000 }).catch(() => {\n          // Navigation may \"fail\" because the response is a download,\n          // not a page. The download event handles it.\n        });\n        const download = await downloadPromise;\n        const failure = await download.failure();\n        if (failure) {","sourceCodeStart":1189,"sourceCodeEnd":1225,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/write-commands.ts#L1189-L1225","documentation":"Error \"Failed to decode blob data\" thrown in garrytan/gstack.","triggerScenarios":"Thrown at browse/src/write-commands.ts:1207 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}