run-llama/llama_index · error · NotImplementedError

This object node mapping does not support persist method.

Error message

This object node mapping does not support persist method.

What it means

BaseToolNodeMapping (and by inheritance SimpleToolNodeMapping) does not implement persistence: from_persist_dir raises NotImplementedError with this message. Tools typically wrap live engines/LLM clients that cannot be pickled, so the mapping must be rebuilt from the actual tool objects at runtime.

Source

Thrown at llama-index-core/llama_index/core/objects/tool_node_mapping.py:61

    @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,
        persist_dir: str = DEFAULT_PERSIST_DIR,
        obj_node_mapping_fname: str = DEFAULT_PERSIST_FNAME,
    ) -> "BaseToolNodeMapping":
        raise NotImplementedError(
            "This object node mapping does not support persist method."
        )


class SimpleToolNodeMapping(BaseToolNodeMapping):
    """
    Simple Tool mapping.

    In this setup, we assume that the tool name is unique, and
    that the list of all tools are stored in memory.

    """

    def __init__(self, objs: Optional[Sequence[BaseTool]] = None) -> None:
        objs = objs or []
        self._tools = {tool.metadata.name: tool for tool in objs}

    @classmethod

View on GitHub (pinned to afd0fef371)

Solutions

  1. Rebuild the tools in code and pass the mapping at load: ObjectIndex.from_persist_dir(persist_dir, object_node_mapping=SimpleToolNodeMapping.from_objects(tools))
  2. Persist only the index stores (index.storage_context.persist(...)) and reconstruct the ObjectIndex around the loaded index
  3. Keep tool definitions in configuration so tools can be recreated deterministically on startup

Example fix

# before
obj_index = ObjectIndex.from_persist_dir("./storage")  # mapping load fails for tools

# after
tools = [FunctionTool.from_defaults(fn=fn_a), FunctionTool.from_defaults(fn=fn_b)]
mapping = SimpleToolNodeMapping.from_objects(tools)
obj_index = ObjectIndex.from_persist_dir("./storage", object_node_mapping=mapping)
Defensive patterns

Strategy: fallback

Validate before calling

# rebuild mapping from live tools and pass it explicitly — never rely on auto-load for tool mappings
mapping = SimpleToolNodeMapping.from_objects(build_tools())
obj_index = ObjectIndex.from_persist_dir(persist_dir, object_node_mapping=mapping)

Type guard

def mapping_supports_disk_load(mapping_cls) -> bool:
    from llama_index.core.objects import SimpleObjectNodeMapping
    return mapping_cls is SimpleObjectNodeMapping

Try / catch

try:
    obj_index = ObjectIndex.from_persist_dir(persist_dir)
except (NotImplementedError, Exception) as e:
    if "persist" in str(e) or "object_node_mapping" in str(e):
        mapping = SimpleToolNodeMapping.from_objects(build_tools())
        obj_index = ObjectIndex.from_persist_dir(persist_dir, object_node_mapping=mapping)
    else:
        raise

Prevention

When it happens

Trigger: Calling BaseToolNodeMapping.from_persist_dir(persist_dir) directly, or ObjectIndex.from_persist_dir without object_node_mapping when the persisted index was built over tools — the default load path attempts to load a mapping and fails.

Common situations: Persisting a tool ObjectIndex (e.g. for an agent) and trying to restore it in a new process; assuming every ObjectIndex persists the same way as the SimpleObjectNodeMapping examples in the docs.

Related errors


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