gildas-lormeau/SingleFile · error · Error
First argument to Readability constructor should be a docume
Error message
First argument to Readability constructor should be a document object.
What it means
The Readability constructor requires a parsed DOM Document object (something with a .documentElement property) as its first argument. It throws this error when given null/undefined or any non-document value — most commonly a raw HTML string, which older API versions and tutorials mistakenly showed as acceptable.
Source
Thrown at src/lib/readability/Readability.js:33
*/
/*
* This code is heavily based on Arc90's readability.js (1.7.1) script
* available at: http://code.google.com/p/arc90labs-readability
*/
/**
* Public constructor.
* @param {HTMLDocument} doc The document to parse.
* @param {Object} options The options object.
*/
function Readability(doc, options) {
// In some older versions, people passed a URI as the first argument. Cope:
if (options && options.documentElement) {
doc = options;
options = arguments[2];
} else if (!doc || !doc.documentElement) {
throw new Error(
"First argument to Readability constructor should be a document object."
);
}
options = options || {};
this._doc = doc;
this._docJSDOMParser = this._doc.firstChild.__JSDOMParser__;
this._articleTitle = null;
this._articleByline = null;
this._articleDir = null;
this._articleSiteName = null;
this._attempts = [];
this._metadata = {};
// Configurable options
this._debug = !!options.debug;
this._maxElemsToParse =
options.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE;
View on GitHub (pinned to 517fb7c5cf)
Solutions
- Parse the HTML string into a document first: new JSDOM(html).window.document or new DOMParser().parseFromString(html, "text/html")
- If using JSDOM, pass jsdom.window.document, not the JSDOM instance itself
- Check that the fetch/DOM parse step actually produced a document before constructing Readability
- If you intentionally passed a URI in options, ensure options.documentElement handling matches the current library version
Example fix
// before const article = new Readability(htmlString).parse(); // after const doc = new JSDOM(htmlString).window.document; const article = new Readability(doc).parse();
Defensive patterns
Strategy: type-guard
Validate before calling
if (!doc || typeof doc !== "object" || !doc.documentElement) {
throw new Error("Readability requires a Document object, not a string");
} Type guard
function isDocument(obj) {
return obj != null && typeof obj === "object" && obj.nodeType === 9 && !!obj.documentElement;
}
// usage: if (!isDocument(input)) input = new JSDOM(html).window.document; Try / catch
let doc = htmlString ? new JSDOM(htmlString).window.document : maybeDoc;
if (!isDocument(doc)) throw new Error("Could not build a DOM document for Readability");
try {
const article = new Readability(doc).parse();
} catch (e) {
if (e.message.includes("First argument to Readability")) throw new Error("Input HTML failed to parse into a document");
throw e;
} Prevention
- Always parse HTML strings via JSDOM/DOMParser before Readability
- Pass jsdom.window.document, never the JSDOM wrapper
- Check DOMParser results for parsererror elements
- Pin library version and follow its current constructor docs
When it happens
Trigger: new Readability(htmlString) instead of a DOM document; passing null/undefined because the page fetch or DOMParser.parseFromString returned an error document or nothing; passing a JSDOM instance instead of its window.document.
Common situations: Following outdated examples that passed an HTML string or URI; mixing up JSDOM object with its .window.document; DOMParser failing silently in non-browser environments; response body not parsed into a document before constructing.
Related errors
- SingleFile capture config must be an object
- Aborting parsing document; " + numTags + " elements found
AI-assisted analysis of gildas-lormeau/SingleFile@517fb7c5cf (2026-09-01).
Data as JSON: /api/errors/0641b20d7143f432.
Report an issue: GitHub.