{"record":{"id":"e9bce3b94f68649c","repo":"iflytek/astron-agent","slug":"websocketclientautherror","errorCode":"WebSocketClientAuthError","errorMessage":"ASE 鉴权失败","messagePattern":"ASE 鉴权失败","errorType":"error_code","errorClass":"WebSocketClientException","httpStatus":null,"severity":"error","filePath":"core/plugin/aitools/common/clients/websockets_client.py","lineNumber":86,"sourceCode":"        \"\"\"Start async WebSocket client\"\"\"\n        await self.connect()\n        yield self\n\n    def _auth(self) -> None:\n        \"\"\"Build WebSocket URL\"\"\"\n        try:\n            if \"auth\" in self.kwargs and self.kwargs[\"auth\"] == \"ASE\":\n\n                method = self.kwargs.get(\"method\", \"GET\")\n                api_key = self.kwargs.get(\"api_key\", \"\")\n                api_secret = self.kwargs.get(\"api_secret\", \"\")\n                new_url = HMACAuth.build_auth_request_url(\n                    self.url, method, api_key, api_secret\n                )\n\n                if new_url is None:\n                    log.error(\"WebSocket auth failed\")\n                    raise WebSocketClientException.from_error_code(\n                        CodeEnums.WebSocketClientAuthError, extra_message=\"ASE 鉴权失败\"\n                    )\n\n                self.url = new_url\n        except Exception:\n            raise\n\n    async def connect(self) -> None:\n        \"\"\"Connect to WebSocket server\"\"\"\n        try:\n            self.ws = await websockets.connect(self.url, **self.ws_params)\n            self._running = True\n        except Exception as e:\n            raise WebSocketClientException.from_error_code(\n                CodeEnums.WebSocketClientNotConnectedError, extra_message=str(e)\n            )\n\n        self._tasks.append(self.task_factory.create(self._send_loop()))","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/plugin/aitools/common/clients/websockets_client.py#L68-L104","documentation":"WebSocketClientAuthError (via WebSocketClientException.from_error_code) raised in WebSocketClient._auth when HMACAuth.build_auth_request_url returns None, meaning the ASE HMAC signature could not be built for the WebSocket URL. In practice this happens when the API key or secret passed to the constructor is missing/empty or the auth URL construction fails, so the signed URL is never produced and the client aborts at construction time.","triggerScenarios":"Constructing WebSocketClient(url, auth='ASE') where the 'api_key'/'api_secret' kwargs are absent, empty strings (the .get(..., \"\") defaults), or contain characters HMACAuth cannot sign; also when self.url is malformed such that build_auth_request_url fails and returns None.","commonSituations":"Missing API key/secret in environment or config after a deployment; renamed kwarg (e.g. passing 'apiKey' instead of 'api_key') so the default '' kicks in; expired or revoked ASE credentials; wrong auth method value while auth='ASE' is still set.","solutions":["Verify you pass non-empty api_key and api_secret kwargs: WebSocketClient(url, auth='ASE', api_key=os.environ['ASE_API_KEY'], api_secret=os.environ['ASE_API_SECRET'])","Log/inspect the kwargs reaching _auth — a typo in the kwarg name silently falls back to '' via self.kwargs.get('api_key', '')","Confirm the credentials are valid and active in the ASE console; regenerate if revoked","Check that self.url is a well-formed ws:// or wss:// URL that HMACAuth.build_auth_request_url can sign"],"exampleFix":"// before\nclient = WebSocketClient(url, auth=\"ASE\")  # no api_key/api_secret -> build_auth_request_url returns None\n// after\nclient = WebSocketClient(\n    url,\n    auth=\"ASE\",\n    api_key=os.environ[\"ASE_API_KEY\"],\n    api_secret=os.environ[\"ASE_API_SECRET\"],\n    method=\"GET\",\n)","handlingStrategy":"try-catch","validationCode":"def ase_credentials_ready(kwargs: dict) -> bool:\n    return bool(kwargs.get(\"auth\") == \"ASE\"\n                and kwargs.get(\"api_key\")\n                and kwargs.get(\"api_secret\"))","typeGuard":null,"tryCatchPattern":"from plugin.aitools.common.clients.exceptions import WebSocketClientException  # adjust import to project layout\ntry:\n    client = WebSocketClient(url, auth=\"ASE\", api_key=key, api_secret=secret)\nexcept WebSocketClientException as e:\n    log.error(\"ASE WebSocket auth failed; check api_key/api_secret kwargs: %s\", e)\n    raise","preventionTips":["Always pass api_key and api_secret explicitly; missing kwargs silently become '' via .get(..., '')","Load credentials from environment at startup and fail fast if missing","Use exact kwarg names (api_key, api_secret, method) — camelCase typos fall through to defaults","Verify ASE credentials are active before deployment; rotate via config rather than hardcoding"],"tags":["authentication","websocket","hmac","missing-credentials","python"],"backgroundTag":"authentication-required","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"}