gildas-lormeau/SingleFile · error · Error
response.error
Error message
response.error
What it means
In downloadCompressedContent, when the page must be saved in the foreground (foregroundSave, or non-background save / sharePage), downloadPageForeground's response is checked and any truthy response.error is re-thrown as Error(response.error). This surfaces whatever error the foreground save dialog/pipeline reported (e.g. save cancelled, download interrupted) as the thrown message.
Source
Thrown at src/core/bg/downloads.js:343
tabIndex: tab.index + 1,
filename: message.filename,
content: Array.from(new Uint8Array(await blob.arrayBuffer())),
compressContent: message.compressContent,
selfExtractingArchive: message.selfExtractingArchive,
disableCompression: message.disableCompression,
extractDataFromPage: message.extractDataFromPage,
insertTextBody: message.insertTextBody,
insertMetaCSP: message.insertMetaCSP,
embeddedImage: message.embeddedImage,
url: message.originalUrl
});
} else if (message.foregroundSave || !message.backgroundSave || message.sharePage) {
const response = await downloadPageForeground(message.taskId, message.filename, blob, pageData.mimeType, tabId, {
foregroundSave: true,
sharePage: message.sharePage
});
if (response.error) {
throw new Error(response.error);
}
} else if (message.saveWithWebDAV) {
response = await saveWithWebDAV(message.taskId, encodeSharpCharacter(message.filename), blob, message.webDAVURL, message.webDAVUser, message.webDAVPassword, { filenameConflictAction: message.filenameConflictAction, prompt });
} else if (message.saveWithMCP) {
response = await saveWithMCP(message.taskId, encodeSharpCharacter(message.filename), blob, message.mcpServerUrl, message.mcpAuthToken, { filenameConflictAction: message.filenameConflictAction, prompt });
} else if (message.saveToGDrive) {
await saveToGDrive(message.taskId, encodeSharpCharacter(message.filename), blob, {
forceWebAuthFlow: message.forceWebAuthFlow
}, {
onProgress: (offset, size) => ui.onUploadProgress(tabId, offset, size),
filenameConflictAction: message.filenameConflictAction,
prompt
});
} else if (message.saveToDropbox) {
await saveToDropbox(message.taskId, encodeSharpCharacter(message.filename), blob, {
onProgress: (offset, size) => ui.onUploadProgress(tabId, offset, size),
filenameConflictAction: message.filenameConflictAction,
promptView on GitHub (pinned to 517fb7c5cf)
Solutions
- Catch and inspect err.message — it is the raw foreground-save error string; handle known values (e.g. cancellations) distinctly.
- Retry with backgroundSave instead of foregroundSave to bypass the interactive path.
- Check the response.error string for 'cancelled' vs real failures to decide whether to surface to the user.
Example fix
// before
await downloadTabPage(tabId, { ...message, foregroundSave: true });
// after
try { await downloadTabPage(tabId, { ...message, foregroundSave: true }); }
catch (err) {
if (/cancel/i.test(err.message)) return; // user cancelled Save As
throw err;
} Defensive patterns
Strategy: try-catch
Try / catch
try { await downloadTabPage(tabId, message); } catch (e) { if (/cancel/i.test(e.message)) return; throw e; } Prevention
- Inspect err.message — it carries the raw foreground-save error string
- Offer a backgroundSave fallback path
- Distinguish user cancellations from real download failures before reporting
When it happens
Trigger: Calling downloadTabPage with foregroundSave true (or backgroundSave false / sharePage true) and downloadPageForeground returns { error: '...' } — e.g. the browser download was cancelled, blocked, or failed.
Common situations: User cancels the browser 'Save As' dialog; download filename conflicts resolved as failure; share-sheet errors on mobile; disk/permission failures in the foreground save path.
Related errors
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/d3c66d9b884dcc79.
Report an issue: GitHub.