run-llama/llama_index · 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

Raised by BaseDocumentStore.get_node (sync) when the object stored under node_id exists in the docstore but is not an instance of BaseNode. get_node first fetches via get_document; if that returns a non-BaseNode object (e.g. a raw dict, a legacy Document schema object, or data deserialized by a custom store incorrectly), the isinstance check fails and this ValueError is thrown. It signals corrupted or incompatible docstore contents rather than a missing node (a missing node raises 'Node {node_id} not found' instead).

Source

Thrown at llama-index-integrations/readers/llama-index-readers-web/llama_index/readers/web/readability_web/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 = [];

  // Configurable options
  this._debug = !!options.debug;
  this._maxElemsToParse =
    options.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE;
  this._nbTopCandidates =

View on GitHub (pinned to afd0fef371)

Solutions

  1. Inspect what get_document(node_id) actually returns: print(type(docstore.get_document(node_id, raise_error=False))) to identify the offending type.
  2. If the store holds raw dicts, re-insert nodes properly via docstore.add_documents([...]) using BaseNode objects (TextNode, Document, etc.) so serialization goes through doc_to_dict.
  3. If data was persisted by an older llama-index version, rebuild the docstore from source documents and re-persist.
  4. If using a custom DocumentStore, ensure get_document deserializes with llama_index.core.storage.docstore.utils.json_to_doc / legacy_json_to_doc so it returns BaseNode instances.

Example fix

# before
raw = {"text": "hello", "id_": "n1"}
docstore.put_document(raw)  # stores non-BaseNode
docstore.get_node("n1")  # ValueError: Document n1 is not a Node.

# after
from llama_index.core.schema import TextNode
node = TextNode(id_="n1", text="hello")
docstore.add_documents([node], allow_update=True)
docstore.get_node("n1")  # ok
Defensive patterns

Strategy: type-guard

Validate before calling

doc = docstore.get_document(node_id, raise_error=False)
if doc is None or not isinstance(doc, BaseNode):
    # do not call get_node with raise_error=True
    ...

Type guard

from llama_index.core.schema import BaseNode

def is_stored_node(docstore, node_id: str) -> bool:
    doc = docstore.get_document(node_id, raise_error=False)
    return isinstance(doc, BaseNode)

Try / catch

try:
    node = docstore.get_node(node_id)
except ValueError as e:
    if "not a Node" in str(e):
        # corrupt entry: re-ingest or quarantine node_id
        ...
    else:
        raise

Prevention

When it happens

Trigger: Calling docstore.get_node(node_id) where the stored value was written without proper serialization (e.g. a plain dict was put into the store), or reading a docstore persisted by an incompatible/older llama-index version whose deserialization (doc_to_dict/json_to_doc) produced an unexpected type, or a custom DocumentStore implementation whose get_document returns a Document typed object that is not a BaseNode subclass.

Common situations: Upgrading llama-index across major versions and reusing persisted SimpleDocumentStore JSON files; custom docstore backends that store raw dicts; stores populated by external processes that bypass add_documents; partially migrated legacy data using legacy_json_to_doc.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/921d0365fd5da90e. Report an issue: GitHub.