{"record":{"id":"6c48c86591ccdd1a","repo":"run-llama/llama_index","slug":"handoff-is-a-reserved-tool-name-please-use-a-di","errorCode":null,"errorMessage":"'handoff' is a reserved tool name. Please use a different name.","messagePattern":"'handoff' is a reserved tool name\\. Please use a different name\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"llama-index-core/llama_index/core/agent/workflow/base_agent.py","lineNumber":228,"sourceCode":"        \"\"\"\n        Validate tools.\n\n        If tools are not of type BaseTool, they will be converted to FunctionTools.\n        This assumes the inputs are tools or callable functions.\n        \"\"\"\n        if v is None:\n            return None\n\n        validated_tools: List[BaseTool] = []\n        for tool in v:\n            if not isinstance(tool, BaseTool):\n                validated_tools.append(FunctionTool.from_defaults(tool))\n            else:\n                validated_tools.append(tool)\n\n        for tool in validated_tools:\n            if tool.metadata.name == \"handoff\":\n                raise ValueError(\n                    \"'handoff' is a reserved tool name. Please use a different name.\"\n                )\n\n        return validated_tools  # type: ignore[return-value]\n\n    def _get_prompts(self) -> PromptDictType:\n        \"\"\"Get prompts.\"\"\"\n        return {}\n\n    def _get_prompt_modules(self) -> PromptMixinType:\n        \"\"\"Get prompt sub-modules.\"\"\"\n        return {}\n\n    def _update_prompts(self, prompts_dict: PromptDictType) -> None:\n        \"\"\"Update prompts.\"\"\"\n\n    @abstractmethod\n    async def take_step(","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/agent/workflow/base_agent.py#L210-L246","documentation":"MutableMappingKVStore.persist unconditionally raises NotImplementedError; it exists only so type checkers accept the method on the base class. Persistence is a capability of concrete dict-backed stores like SimpleKVStore, which implements persist(persist_path, fs) to write JSON; calling it on the base (or a subclass that inherits it) means you asked a non-persistable store to persist.","triggerScenarios":"Calling kvstore.persist('store.json') on an instance of MutableMappingKVStore or a subclass that does not override persist (e.g. a custom in-memory store); generic code that receives a MutableMappingKVStore-typed value and assumes persistence.","commonSituations":"Pluggable storage configurations where a custom or third-party store replaces SimpleKVStore but persistence code paths (StorageContext.persist, docstore.persist) were not updated; type annotations widened to MutableMappingKVStore letting non-persistable stores flow into persist calls.","solutions":["Use SimpleKVStore (or a subclass that implements persist) when you need to persist to disk.","Override persist in your custom store: serialize self._data with json.dump to persist_path.","Branch on capability: if isinstance(store, SimpleKVStore): store.persist(...) else: <export via your own mechanism>.","Rely on your backend's native durability (e.g. MongoDB/Redis stores persist implicitly) instead of persist()."],"exampleFix":"# before\nkvstore: MutableMappingKVStore = CustomKVStore()\nkvstore.persist(\"out.json\")  # NotImplementedError\n\n# after\nimport json\nclass CustomKVStore(MutableMappingKVStore):\n    def persist(self, persist_path, fs=None):\n        with open(persist_path, \"w\") as f:\n            json.dump(self._data, f)","handlingStrategy":"type-guard","validationCode":"if not hasattr(type(kvstore), 'persist') or type(kvstore).persist is MutableMappingKVStore.persist:\n    raise TypeError('store cannot persist; use SimpleKVStore')\nkvstore.persist(path)","typeGuard":"from llama_index.core.storage.kvstore.simple_kvstore import SimpleKVStore\nfrom llama_index.core.storage.kvstore.types import MutableMappingKVStore\n\ndef is_persistable(store) -> bool:\n    return not (type(store).persist is MutableMappingKVStore.persist)","tryCatchPattern":"try:\n    kvstore.persist('out.json')\nexcept NotImplementedError:\n    # export via store-native mechanism instead\n    ...","preventionTips":["Implement persist in custom MutableMappingKVStore subclasses.","Only annotate variables as the concrete persistable type when persistence is required.","Prefer SimpleKVStore when disk snapshots are part of the workflow."],"tags":["kvstore","persistence","not-implemented","custom-store"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}