gildas-lormeau/SingleFile · error · Error
SingleFile capture config must be an object
Error message
SingleFile capture config must be an object
What it means
getCaptureConfig validates the optional 'config' field of an external capture message. null/undefined is allowed (defaults to {}), but any non-object value — including arrays — is rejected with 'SingleFile capture config must be an object'. This ensures capture options are a plain map of option names to values.
Source
Thrown at src/core/bg/external-messages.js:150
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;
}
}
}
function getCaptureConfig(message) {
const { config } = message;
if (config == null) {
return {};
}
if (typeof config != "object" || Array.isArray(config)) {
throw new Error("SingleFile capture config must be an object");
}
const captureConfig = {};
CAPTURE_OPTION_NAMES.forEach(optionName => {
if (config[optionName] !== undefined) {
captureConfig[optionName] = config[optionName];
}
});
return captureConfig;
}
async function queryTabs(options) {
const tabs = await browser.tabs.query(options);
return tabs.sort((tab1, tab2) => tab1.index - tab2.index);
}
View on GitHub (pinned to 517fb7c5cf)
Solutions
- Pass config as a plain object keyed by capture option names, e.g. { backgroundSave: true }.
- Parse JSON strings before sending: config = JSON.parse(configStr).
- Convert arrays into an object map before sending.
- Omit the config field entirely if you want defaults.
Example fix
// before
sendMessage({ method: 'capture', config: ['backgroundSave', 'removeHiddenElements'] });
// after
sendMessage({ method: 'capture', config: { backgroundSave: true, removeHiddenElements: true } }); Defensive patterns
Strategy: validation
Validate before calling
function isValidCaptureConfig(config) {
return config == null || (typeof config === 'object' && !Array.isArray(config));
}
if (!isValidCaptureConfig(myConfig)) throw new TypeError('config must be a plain object'); Type guard
function isPlainObject(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v);
} Try / catch
if (!isPlainObject(config) && config != null) {
config = {}; // or normalize/parse before sending
}
await sendMessage({ method: 'capture', config }); Prevention
- Always send config as a plain object, never arrays or JSON strings
- Parse JSON strings before assigning to message.config
- Omit config entirely when you want defaults
When it happens
Trigger: Sending a capture message where message.config is a string, number, boolean, or an Array (arrays are explicitly rejected even though typeof Array === 'object').
Common situations: Callers JSON-stringify their config and forget to parse it; callers pass a list of option names instead of an options map; dynamic config built from query params stays a string.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- URL is empty
- Cannot identify the extension requesting SingleFile capture
- SingleFile capture was not approved for this extension
- First argument to Readability constructor should be a docume
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/b600a6a8b6e54d4f.
Report an issue: GitHub.