{"record":{"id":"9dc7c74cedeeac03","repo":"iflytek/astron-agent","slug":"40023-failed-to-get-link-tool-protocol","errorCode":"40023","errorMessage":"Failed to get link tool protocol","messagePattern":"Failed to get link tool protocol","errorType":"exception","errorClass":"PluginExc","httpStatus":null,"severity":"error","filePath":"core/agent/service/plugin/link.py","lineNumber":254,"sourceCode":"                    tl_id = tool_id.get(\"tool_id\", \"\")\n                    tl_version = tool_id.get(\"version\", \"\")\n                    url += \"&tool_ids=\" + tl_id + \"&versions=\" + tl_version\n            sp.add_info_events(attributes={\"link-plugin-tool-schema-list-inputs\": url})\n            async with aiohttp.ClientSession() as session:\n                async with session.get(url) as response:\n                    response.raise_for_status()\n                    if response.status == 200:\n                        result = await response.json()\n                        sp.add_info_events(\n                            attributes={\n                                \"link-plugin-tool-schema-list-outputs\": (\n                                    json.dumps(result, ensure_ascii=False)\n                                )\n                            }\n                        )\n                        print(result)\n                        if result.get(\"code\") != 0:\n                            raise GetToolSchemaExc\n                        tools_data = result.get(\"data\", {}).get(\"tools\", [])\n                        return tools_data if isinstance(tools_data, list) else []\n\n                    sp.add_info_events(\n                        attributes={\n                            \"link-plugin-tool-schema-list-outputs\": (\n                                f\"response code is {response.status}\"\n                            )\n                        }\n                    )\n                    raise GetToolSchemaExc\n\n    @staticmethod\n    def parse_request_query_schema(\n        query_schema: list[dict[str, Any]],\n    ) -> tuple[dict[str, dict[str, Any]], set[str]]:\n        \"\"\"Parse parameters\"\"\"\n","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/agent/service/plugin/link.py#L236-L272","documentation":"GetToolSchemaExc raised in LinkPluginRunner.tool_schema_list (link.py:254). The link-plugin HTTP service responded with HTTP 200 but its business payload has code != 0, meaning the remote plugin rejected the tool-schema-list request. The wrapper converts that business-level failure into a single opaque plugin exception with code 40023 and message 'Failed to get link tool protocol'; the upstream error detail is only visible in the printed result / span events.","triggerScenarios":"Calling BasePlugin.parse_react_schema_list -> LinkPluginRunner.tool_schema_list, POSTing to the link plugin's schema-list endpoint, and receiving a JSON body whose 'code' field is not 0 (e.g. auth rejection, invalid app_id/tool_id, plugin-internal error).","commonSituations":"Expired or wrong link-plugin credentials (app_id/uid), the link plugin service being partially degraded while still returning 200 with an error code, tool_id not existing on the remote side, or version mismatch between agent and link plugin API.","solutions":["Check the span event 'link-plugin-tool-schema-list-outputs' and the printed `result` to read the real error code/message returned by the link plugin.","Verify LINK plugin endpoint env vars and credentials (app_id, uid, tool_id, version) are correct and not expired.","Confirm the link plugin service is healthy (logs/health endpoint) and retry the request.","Confirm agent and link plugin API versions are compatible; redeploy or upgrade the plugin service if the protocol changed."],"exampleFix":"// before: opaque re-raise hides remote detail\nif result.get(\"code\") != 0:\n    raise GetToolSchemaExc\n// after: carry the remote code/message for debugging\nif result.get(\"code\") != 0:\n    raise GetToolSchemaExc(\n        f\"link tool schema list failed: code={result.get('code')} msg={result.get('message')}\"\n    )","handlingStrategy":"try-catch","validationCode":"if not (app_id and uid and tool_id and version):\n    raise ValueError(\"link plugin credentials/app_id/tool_id/version must be set before tool_schema_list\")","typeGuard":"def is_valid_schema_payload(resp: dict) -> bool:\n    return isinstance(resp, dict) and resp.get(\"code\") == 0 and isinstance(resp.get(\"data\", {}).get(\"tools\", []), list)","tryCatchPattern":"try:\n    tools = await runner.tool_schema_list(span)\nexcept GetToolSchemaExc as e:\n    logger.error(\"link tool schema list failed: %s\", e)\n    tools = []  # or re-raise depending on criticality","preventionTips":["Keep link plugin app_id/uid/tool_id/version in validated config, checked at startup","Monitor link plugin service health and alert on non-zero business codes","Log the remote response body before re-raising so the real cause is diagnosable","Pin agent/link plugin API versions together in deployment"],"tags":["plugin","http","upstream-api","aiohttp"],"backgroundTag":"api-error-response","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"}