run-llama/llama_index · error · ValueError

Metadata must be set

Error message

Metadata must be set

What it means

SQLTableNodeMapping._from_node reconstructs a SQLTableSchema from a retrieved node's metadata (keys 'name' and 'context'). It raises ValueError('Metadata must be set') when node.metadata is None. In practice nodes loaded from a docstore usually carry metadata={} (falsy-safe) so this fires mostly with hand-built TextNodes or nodes whose metadata was explicitly cleared.

Source

Thrown at llama-index-core/llama_index/core/objects/table_node_mapping.py:74

        if obj.context_str is not None:
            table_text += f"Context of table {obj.table_name}:\n"
            table_text += obj.context_str
            metadata["context"] = obj.context_str

        table_identity = f"{obj.table_name}{obj.context_str}"

        return TextNode(
            id_=str(uuid.uuid5(namespace=uuid.NAMESPACE_DNS, name=table_identity)),
            text=table_text,
            metadata=metadata,
            excluded_embed_metadata_keys=["name", "context"],
            excluded_llm_metadata_keys=["name", "context"],
        )

    def _from_node(self, node: BaseNode) -> SQLTableSchema:
        """From node."""
        if node.metadata is None:
            raise ValueError("Metadata must be set")
        return SQLTableSchema(
            table_name=node.metadata["name"], context_str=node.metadata.get("context")
        )

    @property
    def obj_node_mapping(self) -> Dict[int, Any]:
        """The mapping data structure between node and object."""
        raise NotImplementedError("Subclasses should implement this!")

    def persist(
        self, persist_dir: str = ..., obj_node_mapping_fname: str = ...
    ) -> None:
        """Persist objs."""
        raise NotImplementedError("Subclasses should implement this!")

    @classmethod
    def from_persist_dir(
        cls,

View on GitHub (pinned to afd0fef371)

Solutions

  1. Ensure nodes passed to from_node carry metadata={'name': <table_name>} (and optionally 'context')
  2. Construct nodes through the mapping itself (mapping.to_node(SQLTableSchema(...))) so ids/metadata are consistent
  3. Guard with `if not node.metadata:` before calling from_node and log which node is malformed

Example fix

# before
node = TextNode(text="Schema of table city: ...")  # metadata missing
schema = mapping.from_node(node)  # ValueError: Metadata must be set

# after
node = mapping.to_node(SQLTableSchema(table_name="city", context_str="city stats"))
schema = mapping.from_node(node)
Defensive patterns

Strategy: validation

Validate before calling

if not node.metadata or "name" not in node.metadata:
    raise ValueError(f"node {node.id_} lacks metadata['name']; rebuild via mapping.to_node()")
schema = mapping.from_node(node)

Type guard

def node_has_table_metadata(node) -> bool:
    return bool(node.metadata) and "name" in node.metadata

Try / catch

try:
    schema = mapping.from_node(node)
except ValueError as e:
    if "Metadata must be set" in str(e):
        skip_or_rebuild(node)  # log and skip malformed node instead of failing the loop
    else:
        raise

Prevention

When it happens

Trigger: Calling mapping.from_node(node) on a TextNode constructed without metadata (TextNode(text=...) leaves metadata={} in current versions; older/manual nodes can be None), or calling the private _from_node directly during ObjectIndex retrieval when metadata was stripped.

Common situations: Unit tests with synthetic nodes; custom retrieval pipelines that rebuild nodes and drop metadata; docstores persisted by very old versions where metadata deserialized as None.

Related errors


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