{"record":{"id":"302b18770eec286e","repo":"gildas-lormeau/SingleFile","slug":"cannot-access-the-tab-contents","errorCode":null,"errorMessage":"Cannot access the tab contents","messagePattern":"Cannot access the tab contents","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bg/business.js","lineNumber":234,"sourceCode":"\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst taskInfo = addTask({\n\t\t\t\tstatus: TASK_PENDING_STATE,\n\t\t\t\ttab: {\n\t\t\t\t\tid: tab.id,\n\t\t\t\t\tindex: tab.index,\n\t\t\t\t\turl: tab.url,\n\t\t\t\t\ttitle: tab.title\n\t\t\t\t},\n\t\t\t\toptions: tabOptions,\n\t\t\t\tmethod: \"content.capture\",\n\t\t\t\tresolve,\n\t\t\t\treject\n\t\t\t});\n\t\t\ttaskInfo.cancel = () => reject(new Error(\"SingleFile capture was cancelled\"));\n\t\t\trunTasks();\n\t\t});\n\t}\n\tthrow new Error(\"Cannot access the tab contents\");\n}\n\nfunction addTask(info) {\n\tconst taskInfo = {\n\t\tid: currentTaskId,\n\t\tstatus: info.status,\n\t\ttab: info.tab,\n\t\toptions: info.options,\n\t\tmethod: info.method,\n\t\tresolve: info.resolve,\n\t\treject: info.reject,\n\t\tdone: function (runNextTasks = true) {\n\t\t\tconst index = tasks.findIndex(taskInfo => taskInfo.id == this.id);\n\t\t\tif (index > -1) {\n\t\t\t\ttasks.splice(index, 1);\n\t\t\t\tif (runNextTasks) {\n\t\t\t\t\trunTasks();\n\t\t\t\t}","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/core/bg/business.js#L216-L252","documentation":"captureTab throws this when the tab cannot be captured because its contents are not accessible. Tabs like chrome:// pages, the Web Store, other extensions' pages, or discarded/prerendered tabs do not expose content to content scripts, so no capture can run.","triggerScenarios":"captureTab called on a privileged/protected page (chrome://, edge://, extension pages, Web Store) or a tab without an injectable content script (no host permissions, discarded tab, missing tabId).","commonSituations":"Batch-capturing all open tabs and hitting restricted browser pages; capturing tabs from other windows/profiles; missing 'tabs' or host permissions in manifest; capturing a discarded tab.","solutions":["Filter out non-capturable URLs (chrome://, about:, Web Store) before calling captureTab","Ensure host permissions/content script access is granted for the target URL","Activate the tab and check tab.status === 'complete' and a real http(s)/file URL before capture","Catch the error and skip or report the tab as non-capturable"],"exampleFix":"// before\nconst results = await Promise.all(tabs.map(t => singlefile.captureTab(t)));\n// after\nconst capturable = tabs.filter(t => /^https?:/.test(t.url || ''));\nconst results = [];\nfor (const t of capturable) {\n  try { results.push(await singlefile.captureTab(t)); }\n  catch (e) { if (e.message === 'Cannot access the tab contents') continue; throw e; }\n}","handlingStrategy":"validation","validationCode":"const capturable = tab && tab.id != null && /^https?:/i.test(tab.url || '') && tab.status === 'complete';\nif (!capturable) throw new SkipCapture();","typeGuard":"const canCapture = (tab) => Boolean(tab && typeof tab.id === 'number' && /^https?:/i.test(tab.url || ''));","tryCatchPattern":"try { return await captureTab(tab); } catch (e) { if (e.message === 'Cannot access the tab contents') return skip(tab); throw e; }","preventionTips":["Filter chrome://, about:, and store URLs before capture","Declare host permissions for all URLs you intend to capture","Ensure the tab is active/complete before capturing","Avoid capturing tabs from other profiles or incognito without permission"],"tags":["permissions","browser-api","tab"],"backgroundTag":"tab-contents-inaccessible","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}