{"record":{"id":"464615c78d098a4f","repo":"iflytek/astron-agent","slug":"codeenum-app-get-with-remote-failed-error","errorCode":"CodeEnum.APP_GET_WITH_REMOTE_FAILED_ERROR","errorMessage":"appid is null","messagePattern":"appid is null","errorType":"error_code","errorClass":"CustomException","httpStatus":null,"severity":"error","filePath":"core/workflow/extensions/fastapi/middleware/auth.py","lineNumber":322,"sourceCode":"                \"message\": \"success\",\n                \"data\": {\n                    \"appid\": \"007d72a3\",\n                    \"name\": \"11212311313131\",\n                    \"source\": \"78263c167bab\",\n                    \"desc\": \"12121\"\n                }\n            }\n        \"\"\"\n        code = resp.json().get(\"code\")\n        if code != 0:\n            raise CustomException(\n                CodeEnum.APP_GET_WITH_REMOTE_FAILED_ERROR,\n                cause_error=json.dumps(resp.json(), ensure_ascii=False),\n            )\n\n        app_id = resp.json().get(\"data\", {}).get(\"appid\")\n        if not app_id:\n            raise CustomException(\n                CodeEnum.APP_GET_WITH_REMOTE_FAILED_ERROR,\n                err_msg=\"appid is null\",\n                cause_error=json.dumps(resp.json(), ensure_ascii=False),\n            )\n        await asyncio.to_thread(\n            self._set_app_id_with_cache, credential_cache_digest, app_id\n        )\n        return app_id\n\n    def _get_app_id_with_cache(self, credential_cache_key: str) -> str:\n        \"\"\"\n        Get the app id with cache\n\n        :param credential_cache_key: PBKDF2-HMAC digest of the complete credential pair\n        :return: The app id\n        \"\"\"\n        cache_service = get_cache_service()\n        app_id: str = cache_service[","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/workflow/extensions/fastapi/middleware/auth.py#L304-L340","documentation":"_get_app_source_detail_with_api_key calls a remote app service and expects resp.json()['data']['appid']. If the remote response succeeds but contains no appid, it raises CustomException CodeEnum.APP_GET_WITH_REMOTE_FAILED_ERROR 'appid is null' with the raw response body as cause_error.","triggerScenarios":"The remote app-detail API returns 200 but data is empty, data.appid is absent, or the app record exists without an appid field — typically the API key is valid syntactically but does not map to a real app.","commonSituations":"Revoked or deleted app whose API key still passes format checks; upstream service degraded and returning an error body with 200; response envelope changed (data nested differently) after an API version change.","solutions":["Verify the API key/secret correspond to a live app on the remote service","Inspect cause_error (the remote response body) to see what the remote actually returned","Check the remote service's response schema for version changes to the 'data.appid' path","Add retry/fallback handling if the upstream intermittently returns empty data"],"exampleFix":"# before\napp_id = resp.json().get(\"data\", {}).get(\"appid\")\n# after\napp_id = resp.json().get(\"data\", {}).get(\"appid\")\nif not app_id:\n    logger.warning(f\"remote app lookup returned no appid: {resp.text}\")  # diagnose via cause_error\n    raise ...","handlingStrategy":"try-catch","validationCode":"resp_json = resp.json()\nassert resp_json.get(\"data\", {}).get(\"appid\"), \"remote app lookup returned no appid; verify the app/key exists\"","typeGuard":null,"tryCatchPattern":"try:\n    detail = await middleware._get_app_source_detail_with_api_key(request)\nexcept CustomException as e:\n    if e.err_code == CodeEnum.APP_GET_WITH_REMOTE_FAILED_ERROR:\n        logger.error(f\"remote app lookup failed: {e.cause_error}\")\n        raise HTTPException(status_code=401, detail=\"unknown or revoked app credentials\")\n    raise","preventionTips":["Check cause_error (remote body) when diagnosing","Verify app keys are revoked cleanly on app deletion","Assert the upstream response contract (data.appid) in integration tests","Handle upstream envelope changes behind an adapter"],"tags":["remote-api","response-shape","app-lookup"],"backgroundTag":"unexpected-api-response-shape","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"}