
Spend Logs UI regression: upstream provider failures are hidden because /spend/logs/ui returns metadata as JSON text
快速结论:该报错发生在 LiteLLM Spend Logs UI 中,上游提供商请求失败(如 403)的记录被错误显示为成功,且嵌套错误详情在请求日志行或抽屉组件中丢失。优先排查版本是否包含修复提交 adf7c97714f94eabdcca1ee5c561d5c5b7ee6f01,否则需在 prisma_client.db.query_raw 之后手动反序列化 metadata JSON 文本。
问题场景
用户在 LiteLLM Proxy 中配置上游提供商(如 OpenAI、Anthropic 等)时,当上游返回失败状态码(如 403),LiteLLM 会记录失败元数据(如 status == "failure" 和 metadata.error_information.error_code == "403")。但在 Spend Logs UI 中,这些失败行被显示为成功,且错误详情不可见。问题仅影响 Spend Logs UI 展示层,不影响 OTEL span 数据。
报错原文
issue: upstream provider failures are hidden because /spend/logs/ui returns metadata as JSON text
actual behavior: failed upstream provider calls appear as successful in spend logs UI
expected: failure rows show status="failure" and metadata.error_information.error_code="403"
core observation: spend logs UI still treats log.metadata as an object; reads like:
- metadata.status
- metadata.error_information
root cause: metadata is now a string (JSON text) on this code path, reads fail silently
relevant code paths:
- backend raw sql at litellm/proxy/spend_tracking/spend_management_endpoints.py
- dashboard at:
- ui/litellm-dashboard/src/components/view_logs/columns.tsx
- ui/.../LogDetailsDrawer/LogDetailsDrawer.tsx
- ui/.../LogDetailsDrawer/LogDetailContent.tsx
原因分析
可能原因:LiteLLM Proxy 在版本 v1.88.0-rc.1 及后续版本中,/spend/logs/ui 端点通过原始 SQL 查询数据库并返回 metadata 字段作为 JSON 文本(字符串),而非解析后的对象。Spend Logs UI 前端代码(columns.tsx、LogDetailsDrawer.tsx、LogDetailContent.tsx)仍以对象形式访问 metadata.status 和 metadata.error_information,当 metadata 是字符串时这些读取静默失败,导致失败行看起来像成功行,且错误详情被隐藏。
注意:该修复在 #29682 中实现,但截至 v1.89.2 仍未包含。提交 adf7c97714f94eabdcca1ee5c561d5c5b7ee6f01 之后的版本才可能包含此修复。
环境排查
- LiteLLM 版本:确认是否为
v1.88.0-rc.1、v1.89.1、v1.89.2等受影响版本 - 检查
litellm/proxy/spend_tracking/spend_management_endpoints.py中prisma_client.db.query_raw之后是否有metadataJSON 反序列化代码块 - 确认上游提供商(如 OpenAI)是否返回 403 等失败状态码
- 验证 OTEL span 中
standard_logging_object.error_information是否正常显示错误详情
解决步骤
- 方案一(可优先尝试):更新 LiteLLM 到包含修复的版本(如
v1.90.0或之后版本)。如果无法立即更新,需手动应用补丁。 - 方案二(手动修复):编辑
litellm/proxy/spend_tracking/spend_management_endpoints.py,在data = await prisma_client.db.query_raw(sql_query, *sql_params)之后(约第 2138 行),添加metadataJSON 文本反序列化逻辑。将data中每条记录的metadata字段从 JSON 字符串解析为dict,然后再传递给_build_ui_spend_logs_response()。 - 方案三:修改前端代码,在
columns.tsx、LogDetailsDrawer.tsx、LogDetailContent.tsx中防御性地处理metadata字段:如果是字符串则先JSON.parse(),再访问status和error_information。 - 方案四:优先使用顶层
status字段(如果已选取)替代依赖metadata.status。
验证方法
修复后,模拟上游提供商返回 403 错误,在 Spend Logs UI 中查看对应请求日志行:
- 该行应显示为“失败”状态(红色或错误标志)
- 点击该行打开抽屉(drawer)组件,应能正常显示
error_information.error_code == "403"等错误详情 - 检查
/spend/logs/ui接口返回的 JSON 中,metadata应是一个对象({})而非字符串 - 确认 OTEL span 数据不受影响(之前已正常工作)



