iflytek/astron-agent · error · CustomException
CodeEnum.PARAM_ERROR
CodeEnum.PARAM_ERROR
Error message
authorization header is invalid
What it means
_get_app_source_detail_with_api_key parses the Authorization header as 'Bearer <api_key>:<api_secret>' in two split steps. If the header lacks the expected separators (no space or no colon), split raises ValueError, which is converted to CustomException with CodeEnum.PARAM_ERROR 'authorization header is invalid'.
Solutions
- Send the header as 'Authorization: Bearer <api_key>:<api_secret>'
- Verify both key and secret are present and separated by exactly one colon
- Check the HTTP client is not already prepending 'Bearer ' twice or encoding the credential
- Log/inspect the raw header shape (mask secrets) to confirm the format
Example fix
// before Authorization: Bearer sk-abc123 // after Authorization: Bearer sk-abc123:secret456
Defensive patterns
Strategy: validation
Validate before calling
parts = authorization.split(" ", 1)
ok = len(parts) == 2 and ":" in parts[1]
assert ok, "Authorization must be 'Bearer <api_key>:<api_secret>'" Type guard
def is_valid_auth_header(header: str) -> bool:
parts = header.split(" ", 1)
if len(parts) != 2 or ":" not in parts[1]:
return False
key, secret = parts[1].split(":", 1)
return bool(key and secret) Try / catch
try:
detail = await middleware._get_app_source_detail_with_api_key(request)
except CustomException as e:
if e.err_code == CodeEnum.PARAM_ERROR:
return JSONResponse(status_code=400, content={"message": "Authorization must be 'Bearer key:secret'"})
raise Prevention
- Centralize header construction in one auth helper
- Always include both key and secret separated by ':'
- Add a client-side format check before sending
- Document the expected scheme for SDK consumers
When it happens
Trigger: Sending Authorization headers like 'Bearer abc' (missing ':secret'), 'abc:def' (missing scheme), or a raw token without the Bearer prefix, so ' '.split(...) or ':'.split(...) fails to produce two parts.
Common situations: Clients treating the header as a plain token; SDK updates changing auth format; copy-paste losing the secret part; base64 credentials used where key:secret is expected.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- malformed bearer credential
- missing bearer credential
- -40008
- APP_TENANT_NOT_FOUND_ERROR
- artifact_upload_failed
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/f28b381a4d46d17b.
Report an issue: GitHub.
Appendix: source
Thrown at core/workflow/extensions/fastapi/middleware/auth.py:266
headers[TENANT_INTERNAL_API_KEY_HEADER] = self.api_secret
return headers
async def _get_app_source_detail_with_api_key(
self, authorization: str, span: Span
) -> str:
"""
Get the app source detail with api key
:param authorization: The authorization header
:param span: The span object
:return: The app source detail
"""
try:
scheme, credential = authorization.split(" ", 1)
api_key, api_secret = credential.strip().split(":", 1)
except ValueError as exc:
raise CustomException(
CodeEnum.PARAM_ERROR,
err_msg="authorization header is invalid",
) from exc
if scheme.lower() != "bearer" or not api_key or not api_secret:
raise CustomException(
CodeEnum.PARAM_ERROR,
err_msg="authorization header is invalid",
)
credential_cache_digest = credential_cache_key(credential.strip())
app_id = await asyncio.to_thread(
self._get_app_id_with_cache, credential_cache_digest
)
if app_id:
return app_id
base_url = os.getenv("APP_MANAGE_PLAT_BASE_URL", "").rstrip("/")View on GitHub (pinned to 5e758547a8)