{"record":{"id":"554799f3bacfb388","repo":"iflytek/astron-agent","slug":"no-field-attr-found-in-tool-info","errorCode":null,"errorMessage":"no {field} attr found in tool info!","messagePattern":"no (.+?) attr found in tool info!","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"core/plugin/link/service/community/tools/http/management_server.py","lineNumber":289,"sourceCode":"    for tool_id in tool_ids:\n        if not re.compile(\"^tool@[0-9a-zA-Z]+$\").match(tool_id):\n            return f\"tool id {tool_id} illegal\"\n    return None\n\n\ndef process_tools_for_update(\n    tools: List[Dict[str, Any]], app_id: Optional[str], span_context: Any\n) -> Tuple[Optional[List[Dict[str, Any]]], List[str]]:\n    \"\"\"Process tools for update, including validation.\"\"\"\n    update_tool = []\n    tool_ids = []\n\n    for tool in tools:\n        # Validate required fields\n        required_fields = [\"version\", \"name\", \"description\", \"openapi_schema\"]\n        for field in required_fields:\n            if field not in tool:\n                raise Exception(f\"no {field} attr found in tool info!\")\n\n        schema_content = tool.get(\"openapi_schema\", \"\")\n        if schema_content:\n            validated_schema, err = validate_openapi_schema(tool, span_context)\n            if err:\n                raise Exception(\n                    f\"update tool: failed to validate tool {tool.get('id')} schema, \"\n                    f\"reason {json.dumps(err)}\"\n                )\n            schema_content = validated_schema\n\n        update_tool.append(\n            {\n                \"app_id\": app_id,\n                \"tool_id\": tool.get(\"id\"),\n                \"name\": tool.get(\"name\"),\n                \"description\": tool.get(\"description\"),\n                \"open_api_schema\": schema_content,","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/link/service/community/tools/http/management_server.py#L271-L307","documentation":"Generic Exception raised in process_tools_for_update when an incoming tool payload is missing one of the required fields: version, name, description, or openapi_schema. It is input validation guarding the tool update (version bump) flow.","triggerScenarios":"update_version -> process_tools_for_update iterates the tools array and a tool dict lacks any required field — e.g. client submits a partial PATCH-like body with only 'name' or omits 'openapi_schema'.","commonSituations":"API consumers send partial updates instead of full tool objects; frontend form not sending all fields; bulk import files missing columns; field renamed client/server after a version change.","solutions":["Include all required fields (version, name, description, openapi_schema) in every tool entry sent to the update endpoint.","Log which tool/index failed (the message names the field but not the tool) to pinpoint the offending entry.","Use Pydantic/dataclass models with required fields so FastAPI returns a precise 422 automatically.","Improve the message to include tool name/id: f\"tool missing {field}: {tool.get('name')}\"."],"exampleFix":"// before\nraise Exception(f\"no {field} attr found in tool info!\")\n// after\nclass ToolUpdateSchema(BaseModel):\n    version: str\n    name: str\n    description: str\n    openapi_schema: str\n# FastAPI rejects incomplete payloads with a 422 naming the missing fields","handlingStrategy":"validation","validationCode":"REQUIRED = {\"version\", \"name\", \"description\", \"openapi_schema\"}\ndef tool_payload_ok(tool: dict) -> bool:\n    return REQUIRED.issubset(tool) and all(tool[f] for f in REQUIRED)","typeGuard":null,"tryCatchPattern":"try:\n    process_tools_for_update(tools, span_context)\nexcept Exception as e:\n    return error_response(400, str(e))","preventionTips":["Send full tool objects on update, not partial patches","Use typed request models (Pydantic) for automatic 422s","Include tool id/name in validation error messages"],"tags":["validation","openapi","api-input"],"backgroundTag":"missing-required-argument","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}