{"record":{"id":"58e3dbcead7aa991","repo":"can1357/oh-my-pi","slug":"aborting-parsing-document-count-elements-found","errorCode":null,"errorMessage":"Aborting parsing document; ${count} elements found","messagePattern":"Aborting parsing document; (.+?) elements found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/utils/src/readability/readability.ts","lineNumber":299,"sourceCode":"\treadonly #document: ReadabilityDocument;\n\treadonly #options: ReadabilityOptions<T>;\n\treadonly #scores = new Map<ReadabilityElement, number>();\n\t#byline: string | undefined;\n\t#lang: string | null = null;\n\n\tconstructor(document: ReadabilityDocument, options: ReadabilityOptions<T> = {}) {\n\t\tthis.#document = document;\n\t\tthis.#options = options;\n\t}\n\n\t/** Runs extraction once; the supplied document is consumed and should not be reused. */\n\tparse(): ReadabilityArticle<T> | null {\n\t\tconst documentElement = this.#document.documentElement;\n\t\tif (!documentElement) return null;\n\t\tconst max = this.#options.maxElemsToParse ?? 0;\n\t\tif (max > 0) {\n\t\t\tconst count = descendants(documentElement).length + 1;\n\t\t\tif (count > max) throw new Error(`Aborting parsing document; ${count} elements found`);\n\t\t}\n\t\tconst jsonLd = this.#options.disableJSONLD ? {} : jsonLdMetadata(this.#document);\n\t\tconst metadata = metadataFromDocument(this.#document, jsonLd);\n\t\tremoveAll(this.#document, [\"script\", \"style\"]);\n\t\tconst body = this.#document.body;\n\t\tif (!body) return null;\n\t\tconst source = body.innerHTML;\n\t\tconst attempts: Attempt[] = [];\n\t\tfor (const mode of [0, 1, 2, 3]) {\n\t\t\tif (mode) body.innerHTML = source;\n\t\t\tthis.#scores.clear();\n\t\t\tthis.#byline = undefined;\n\t\t\tconst attempt = this.#extract(body, documentElement, metadata.title ?? \"\", mode);\n\t\t\tif (attempt) attempts.push(attempt);\n\t\t\tif (attempt && attempt.length >= (this.#options.charThreshold || 500)) break;\n\t\t}\n\t\tattempts.sort((left, right) => right.length - left.length);\n\t\tconst best = attempts[0];","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/readability/readability.ts#L281-L317","documentation":"Readability's parse() refuses to process documents whose element count exceeds the configured maxElemsToParse, as a safeguard against pathological/huge pages that would consume unbounded time and memory. The count includes all descendants of the document element plus one.","triggerScenarios":"Calling readability.parse() on a document when `options.maxElemsToParse` is set (default 0 = unlimited is bypassed once the option is provided) and the DOM contains more elements than that limit.","commonSituations":"Extracting article content from very large HTML pages (giant tables, generated markup), setting a low limit for memory safety and hitting it on legitimate pages.","solutions":["Raise maxElemsToParse to a value above the expected document size.","Pre-trim the document (strip nav/footer/ads, truncate tables) before parsing.","Remove the maxElemsToParse option (0) to parse unbounded documents if memory allows.","Catch the error and fall back to a simpler text extraction."],"exampleFix":"// before\nnew Readability(doc, { maxElemsToParse: 1000 }).parse();\n// after\nnew Readability(doc, { maxElemsToParse: 50000 }).parse();","handlingStrategy":"validation","validationCode":"const count = doc.documentElement ? doc.getElementsByTagName('*').length + 1 : 0;\nconst max = opts.maxElemsToParse ?? 0;\nif (max > 0 && count > max) {\n  // trim document or raise the limit before calling parse()\n}","typeGuard":null,"tryCatchPattern":"try {\n  article = reader.parse();\n} catch (err) {\n  if (String(err.message).startsWith('Aborting parsing document')) {\n    article = fallbackExtract(doc); // simple text extraction\n  } else throw err;\n}","preventionTips":["Set maxElemsToParse generously relative to your largest expected pages.","Pre-strip boilerplate (nav, footer, scripts) before parsing.","Always provide a fallback extractor for huge/pathological pages."],"tags":["html","parsing","limits"],"backgroundTag":"document-too-large","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}