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,
					prompt

View on GitHub (pinned to 517fb7c5cf)

Solutions

  1. Catch and inspect err.message — it is the raw foreground-save error string; handle known values (e.g. cancellations) distinctly.
  2. Retry with backgroundSave instead of foregroundSave to bypass the interactive path.
  3. 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

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.