{"record":{"id":"a6c4a5544733b8ca","repo":"iflytek/astron-agent","slug":"errcode-tool-not-exist-err","errorCode":"ErrCode.TOOL_NOT_EXIST_ERR","errorMessage":"tools don't exist!","messagePattern":"tools don't exist!","errorType":"error_code","errorClass":"ToolNotExistsException","httpStatus":null,"severity":"error","filePath":"core/plugin/link/infra/tool_crud/process.py","lineNumber":111,"sourceCode":"        description: Update tools\n        \"\"\"\n        with session_getter(self.engine) as session:\n            for tool in tool_info:\n                tool_id = tool.get(\"tool_id\")\n                version = (tool.get(\"version\", const.DEF_VER),)\n                is_deleted = tool.get(\"is_deleted\", const.DEF_DEL)\n                query = (\n                    select(Tools)\n                    .where(\n                        Tools.tool_id == tool_id,\n                        Tools.version == version,\n                        Tools.is_deleted == is_deleted,\n                    )\n                    .order_by(desc(Tools.update_at))\n                )\n                tool_inst = session.exec(query).first()\n                if tool_inst is None:\n                    raise ToolNotExistsException(\n                        code=ErrCode.TOOL_NOT_EXIST_ERR.code,\n                        err_pre=ErrCode.TOOL_NOT_EXIST_ERR.msg,\n                        err=\"tools don't exist!\",\n                    )\n\n                if tool.get(\"name\"):\n                    tool_inst.name = tool.get(\"name\")\n                if tool.get(\"description\"):\n                    tool_inst.description = tool.get(\"description\")\n                if tool.get(\"open_api_schema\"):\n                    tool_inst.open_api_schema = tool.get(\"open_api_schema\")\n                session.add(tool_inst)\n                session.commit()\n\n    def add_tool_version(self, tool_info: List[Dict[str, Any]]) -> None:\n        \"\"\"\n        description: Add tool version\n        \"\"\"","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/link/infra/tool_crud/process.py#L93-L129","documentation":"Raised by update_tools in the link plugin's tool CRUD layer when no Tools row matches the given tool_id/version/is_deleted combination. The SELECT finds nothing, so the update has no target row; instead of silently doing nothing, the code raises ToolNotExistsException carrying ErrCode.TOOL_NOT_EXIST_ERR. It signals that the tool you asked to update is not present (or is soft-deleted) in the tools table.","triggerScenarios":"Calling update_tools with a dict whose tool_id has no row in the tools table, whose version does not match an existing row (note version defaults to const.DEF_VER and is compared as a tuple in the WHERE clause), or whose is_deleted timestamp flag does not match the stored soft-delete value.","commonSituations":"Updating a tool that was already deleted (is_deleted mismatch), passing a version string that differs from the stored one (e.g. 'v1' vs '1'), a typo'd or stale tool_id from a client, or the tool was never registered before an update was attempted.","solutions":["Verify the tool_id/version exists by calling get_tools with the same tool_id/version before updating","Check that the version value exactly matches what add_tool_version stored (including the default const.DEF_VER)","Check the is_deleted flag matches the row's soft-delete value; use delete-aware lookup or re-register the tool","Insert the tool first via add_tool_version if it genuinely does not exist"],"exampleFix":"# before\nprocess.update_tools([{\"tool_id\": \"bad-id\", \"version\": \"v2\", \"name\": \"x\"}])  # raises\n# after\nexisting = process.get_tools([{\"tool_id\": \"bad-id\", \"version\": \"v2\"}], span)\nif not existing:\n    process.add_tool_version([{\"tool_id\": \"bad-id\", \"version\": \"v2\", \"app_id\": app_id, \"name\": \"x\"}])\nelse:\n    process.update_tools([{\"tool_id\": \"bad-id\", \"version\": \"v2\", \"name\": \"x\"}])","handlingStrategy":"validation","validationCode":"def tool_exists(process, tool_id, version, span):\n    return bool(process.get_tools([{\"tool_id\": tool_id, \"version\": version}], span))\n\nif not tool_exists(process, tid, ver, span):\n    raise ValueError(f\"tool {tid}@{ver} not registered\")\nprocess.update_tools([{...}])","typeGuard":"def is_valid_tool_update(d: dict) -> bool:\n    return bool(d.get(\"tool_id\")) and bool(d.get(\"version\"))","tryCatchPattern":"try:\n    process.update_tools(tools)\nexcept ToolNotExistsException as e:\n    logger.error(f\"update target missing: {e.err}\")\n    raise HTTPException(status_code=404, detail=\"tool not found\") from e","preventionTips":["Look up the tool with get_tools before every update","Keep version strings consistent (never mix 'v1' and '1')","Treat soft-deleted tools as non-existent and re-register instead of updating"],"tags":["database","sqlmodel","tool-crud","not-found"],"backgroundTag":"entity-not-found","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}