gildas-lormeau/SingleFile · error · Error

SingleFile capture was not approved for this extension

Error message

SingleFile capture was not approved for this extension

What it means

When an external message requests a page capture (METHOD_CAPTURE_PAGE), SingleFile asks the user (or checks stored rules) via externalCapturePermissions.requestPermission whether this calling extension/site is allowed. If permission is not granted, the handler throws 'SingleFile capture was not approved for this extension'. This is an explicit approval gate for third-party capture requests.

Source

Thrown at src/core/bg/external-messages.js:124

		const tabs = await browser.tabs.query({ currentWindow: true, active: true });
		await business.saveSelectedLinks(tabs[0]);
	} else if (message == ACTION_SAVE_SELECTED) {
		const tabs = await browser.tabs.query({ currentWindow: true, active: true });
		await business.saveTabs(tabs, { selected: true });
	} else if (message == ACTION_SAVE_SELECTED_TABS) {
		const tabs = await queryTabs({ currentWindow: true, highlighted: true });
		await business.saveTabs(tabs);
	} else if (message == ACTION_SAVE_UNPINNED_TABS) {
		const tabs = await queryTabs({ currentWindow: true, pinned: false });
		await business.saveTabs(tabs);
	} else if (message == ACTION_SAVE_ALL_TABS) {
		const tabs = await queryTabs({ currentWindow: true });
		await business.saveTabs(tabs);
	} else if (message && message.method == METHOD_CAPTURE_PAGE) {
		const captureConfig = getCaptureConfig(message);
		const permissionGranted = await externalCapturePermissions.requestPermission(sender, message);
		if (!permissionGranted) {
			throw new Error("SingleFile capture was not approved for this extension");
		}
		const currentTab = message.tabId
			? await browser.tabs.get(message.tabId)
			: (await browser.tabs.query({ currentWindow: true, active: true }))[0];
		if (!currentTab) {
			return false;
		}
		return business.captureTab(currentTab, captureConfig);
	} else if (message && message.method) {
		const tabs = await browser.tabs.query({ currentWindow: true, active: true });
		const currentTab = tabs[0];
		if (currentTab) {
			return autosave.onMessageExternal(message, currentTab, sender);
		} else {
			return false;
		}
	}
}

View on GitHub (pinned to 517fb7c5cf)

Solutions

  1. Open SingleFile's options page and add the requesting origin/extension to the allowed external capture permissions, then retry.
  2. Trigger the request again and approve the permission prompt when shown.
  3. Clear any previously denied permission entry for the sender in stored config so the prompt is re-shown.
  4. Verify the sender identity (extension id / origin) matches what was actually approved.

Example fix

// before: fire and forget capture request that may be denied
browser.runtime.sendMessage(otherExtId, { method: 'capture', ... });
// after: catch and guide user to grant permission
try {
  await browser.runtime.sendMessage(otherExtId, { method: 'capture', ... });
} catch (e) {
  if (String(e.message).includes('not approved')) {
    alert('Open SingleFile options and approve this site for external capture.');
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check stored permission config before requesting capture
const perms = await browser.runtime.sendMessage(singleFileId, { method: 'externalCapture.getPermissions' });
const approved = perms && perms.some(p => location.origin.startsWith(p.origin));

Try / catch

try {
  await browser.runtime.sendMessage(singleFileId, { method: 'capture', ... });
} catch (e) {
  if (String(e.message).includes('not approved')) {
    // surface UI telling the user to approve this origin in SingleFile options
  }
}

Prevention

When it happens

Trigger: An external page/extension sends a capture request and requestPermission returns false — the user denied the prompt, no stored permission exists for the sender's origin, or auto-accept rules don't cover the sender.

Common situations: Integrating SingleFile capture into another web app or extension; the user previously clicked 'deny' so the choice is remembered; testing capture calls from a localhost origin that was never approved.

Related errors


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