gildas-lormeau/SingleFile · error · Error

error.message + " (RestFormApi)"

Error message

error.message + " (RestFormApi)"

What it means

saveToRestFormApi wraps any error from the RestFormApi client upload (new RestFormApi(token, restApiUrl, fileFieldName, urlFieldName).upload(filename, content, url)) and rethrows with an " (RestFormApi)" suffix plus the original error as cause. It identifies the REST form API destination as the failure point.

Source

Thrown at src/core/bg/downloads.js:657

	document.removeEventListener(command, listener);

	function listener(event) {
		event.clipboardData.setData(pageData.mimeType, pageData.content);
		event.clipboardData.setData("text/plain", pageData.content);
		event.preventDefault();
	}
}

async function saveToRestFormApi(taskId, filename, content, url, token, restApiUrl, fileFieldName, urlFieldName) {
	try {
		const taskInfo = business.getTaskInfo(taskId);
		if (!taskInfo || !taskInfo.cancelled) {
			const client = new RestFormApi(token, restApiUrl, fileFieldName, urlFieldName);
			business.setCancelCallback(taskId, () => client.abort());
			return await client.upload(filename, content, url);
		}
	} catch (error) {
		throw new Error(error.message + " (RestFormApi)", { cause: error });
	}
}

async function downloadPageForeground(taskId, filename, content, mimeType, tabId, { foregroundSave, sharePage } = {}) {
	const serializer = yabson.getSerializer({
		filename,
		taskId,
		foregroundSave,
		sharePage,
		content: await content.arrayBuffer(),
		mimeType
	});
	for await (const data of serializer) {
		await browser.tabs.sendMessage(tabId, {
			method: "content.download",
			data: Array.from(data)
		});
	}

View on GitHub (pinned to 517fb7c5cf)

Solutions

  1. Check error.cause for the HTTP status and verify restApiUrl is correct
  2. Confirm fileFieldName and urlFieldName match the server's expected multipart field names
  3. Validate/refresh the token
  4. Test the endpoint manually with a curl multipart POST to compare behavior

Example fix

// before
new RestFormApi(token, 'https://api.example.com/save', 'file', 'url');
// server expects field 'upload'
// after
new RestFormApi(token, 'https://api.example.com/save', 'upload', 'url');
Defensive patterns

Strategy: validation

Validate before calling

try { new URL(restApiUrl); } catch { throw new Error('Invalid RestFormApi URL'); }
if (!token) throw new Error('Missing RestFormApi token');
if (!fileFieldName || !urlFieldName) throw new Error('Missing multipart field names');

Type guard

function hasRestFormConfig(o) {
  try { return !!new URL(o.restApiUrl) && !!o.token && !!o.fileFieldName && !!o.urlFieldName; }
  catch { return false; }
}

Try / catch

try {
  await saveToRestFormApi(taskId, filename, content, restOpts);
} catch (error) {
  if (error.message.endsWith('(RestFormApi)')) {
    console.error('REST save failed:', error.cause);
    // inspect status in cause; fix field names or token
  } else { throw error; }
}

Prevention

When it happens

Trigger: Any rejection inside RestFormApi.upload called from downloadContent/downloadCompressedContent: server unreachable, 401/403 auth, wrong field names, malformed endpoint, or abort.

Common situations: REST API URL wrong or not HTTPS; token missing/expired; server expects multipart fields with different names than fileFieldName/urlFieldName configured; CORS or reverse proxy blocking the POST.

Related errors


AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01). Data as JSON: /api/errors/d60f8fe6d6757d83. Report an issue: GitHub.