iflytek/astron-agent · error · ToolNotExistsException
ErrCode.TOOL_NOT_EXIST_ERR
ErrCode.TOOL_NOT_EXIST_ERR
Error message
tools don't exist!
What it means
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.
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
Example fix
# before
process.update_tools([{"tool_id": "bad-id", "version": "v2", "name": "x"}]) # raises
# after
existing = process.get_tools([{"tool_id": "bad-id", "version": "v2"}], span)
if not existing:
process.add_tool_version([{"tool_id": "bad-id", "version": "v2", "app_id": app_id, "name": "x"}])
else:
process.update_tools([{"tool_id": "bad-id", "version": "v2", "name": "x"}]) Defensive patterns
Strategy: validation
Validate before calling
def tool_exists(process, tool_id, version, span):
return bool(process.get_tools([{"tool_id": tool_id, "version": version}], span))
if not tool_exists(process, tid, ver, span):
raise ValueError(f"tool {tid}@{ver} not registered")
process.update_tools([{...}]) Type guard
def is_valid_tool_update(d: dict) -> bool:
return bool(d.get("tool_id")) and bool(d.get("version")) Try / catch
try:
process.update_tools(tools)
except ToolNotExistsException as e:
logger.error(f"update target missing: {e.err}")
raise HTTPException(status_code=404, detail="tool not found") from e Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/a6c4a5544733b8ca.
Report an issue: GitHub.
Appendix: source
Thrown at core/plugin/link/infra/tool_crud/process.py:111
description: Update tools
"""
with session_getter(self.engine) as session:
for tool in tool_info:
tool_id = tool.get("tool_id")
version = (tool.get("version", const.DEF_VER),)
is_deleted = tool.get("is_deleted", const.DEF_DEL)
query = (
select(Tools)
.where(
Tools.tool_id == tool_id,
Tools.version == version,
Tools.is_deleted == is_deleted,
)
.order_by(desc(Tools.update_at))
)
tool_inst = session.exec(query).first()
if tool_inst is None:
raise ToolNotExistsException(
code=ErrCode.TOOL_NOT_EXIST_ERR.code,
err_pre=ErrCode.TOOL_NOT_EXIST_ERR.msg,
err="tools don't exist!",
)
if tool.get("name"):
tool_inst.name = tool.get("name")
if tool.get("description"):
tool_inst.description = tool.get("description")
if tool.get("open_api_schema"):
tool_inst.open_api_schema = tool.get("open_api_schema")
session.add(tool_inst)
session.commit()
def add_tool_version(self, tool_info: List[Dict[str, Any]]) -> None:
"""
description: Add tool version
"""View on GitHub (pinned to 5e758547a8)