Bedrock and Vertex AI batch file IDs produce URI-unsafe S3 log filenames

这个报错通常出现在使用 LiteLLM 1.98.0 的 S3 请求日志(s3_v2)记录托管 Bedrock 或 Vertex AI 批处理文件时,因为 Bedrock 返回的 s3:// 、Vertex AI 返回的 gs:// 文件 ID 中的冒号没有从日志文件名中剔除,导致下游将文件名当作

快速结论:这个报错通常出现在使用 LiteLLM 1.98.0 的 S3 请求日志(s3_v2)记录托管 Bedrock 或 Vertex AI 批处理文件时,因为 Bedrock 返回的 s3://、Vertex AI 返回的 gs:// 文件 ID 中的冒号没有从日志文件名中剔除,导致下游将文件名当作 URI 路径解析时失败。优先排查 S3 日志回调生成的文件名中是否残留冒号。

适用环境:Issue 已确认的环境为 LiteLLM litellm[proxy]==1.98.0,Python 侧验证使用 python3 -m venv 隔离环境与 pytest,并设置 LITELLM_LOCAL_MODEL_COST_MAP=True;未提供操作系统、CUDA、显卡或依赖版本信息。

最快修复方案:暂无确认的一步修复方案。Issue 中提出的修复方向是在共享文件名清洗逻辑中加入 .replace(":", "_"),但该方案在 Issue 讨论中仅作为“Proposed fix(提议修复)”给出,请按你的部署方式验证后再应用。

注意事项:修复只应针对“生成的”文件名,原始 provider ID(s3://gs://)和请求 JSON payload 必须保持原样;冷存储 GET 请求应继续使用其存储的 key(包括历史上含冒号的 key)原样读取。该修复不保证所有可能配置的路径都变为 URI 安全,仅解决含冒号的生成文件名问题。Vertex AI 场景为源码分析与本地复现确认,Issue 未声称存在真实的 GCP 摄取失败。

问题场景

在 LiteLLM 1.98.0 上启用 S3 请求日志(s3_v2),并通过托管 Bedrock 或 Vertex AI 批处理接口上传文件时触发。底层 provider 的文件上传响应使用云存储 URI 作为文件 ID:Bedrock 返回 s3://example-batch-bucket/litellm-bedrock-files/input.jsonl,Vertex AI 返回 gs://example-batch-bucket/litellm-vertex-files/input.jsonl。日志回调从该响应 ID 派生文件名,虽然把 / 替换成了 _,但保留了 URI scheme 的 :

报错原文

Bedrock and Vertex AI batch file IDs produce URI-unsafe S3 log filenames

time-04-51-06-685889_s3:__example-batch-bucket_litellm-bedrock-files_input.jsonl.json
time-04-51-06-685889_gs:__example-batch-bucket_litellm-vertex-files_input.jsonl.json

java.net.URISyntaxException: Relative path in absolute URI

原因分析

这些文件名本身仍是合法的 S3 object key,问题在于相对 URI 引用的第一段中不允许出现未转义或未消歧的冒号。当消费方(例如 Databricks/Hadoop 目录读取)把这些文件名当作 URI 路径解释时,就会抛出 java.net.URISyntaxException: Relative path in absolute URI。根因定位已通过离线验证确认:BedrockFilesConfig.transform_create_file_response()VertexAIFilesConfig.transform_create_file_response() 返回的 batch 用途 OpenAIFileObjectid 分别为 s3://gs:// URI,而 litellm/integrations/s3.py:get_s3_object_key() 对这两种形式都保留了冒号;S3 v2 通过 get_logging_id() 和这个共享 helper 生成上传 key。真实事故涉及带 s3_v2 的 Bedrock acreate_file 日志,Vertex AI 情况由源码与本地复现确认。

环境排查

  • 确认 LiteLLM 版本是否为 litellm[proxy]==1.98.0
  • 确认是否启用了 S3 请求日志,且使用的是 s3_v2 路径。
  • 确认是否经由 Bedrock 或 Vertex AI 批处理上传文件,并且响应 ID 为 s3://gs:// 或 ARN 形式。
  • 确认下游是否有将日志文件名作为 URI 路径解析的消费方(如 Databricks/Hadoop 目录读取)。
  • Issue 未提供操作系统、CUDA、PyTorch、显卡等信息,无需在无证据时补充。

解决步骤

  1. 先复现并确认文件名中是否残留冒号。可用 Issue 提供的最小复现脚本调用 get_s3_object_key(),分别传入 s3://example-batch-bucket/input.jsonlgs://example-batch-bucket/input.jsonl 以及 ARN 形式的 ID,观察输出 key 的文件名部分。
  2. 按 Issue 验证评论搭建隔离环境:python3 -m venv /tmp/verify-s3-log-filenames,安装 'litellm[proxy]==1.98.0'pytest,设置 LITELLM_LOCAL_MODEL_COST_MAP=True 后运行参数化断言测试,确认在 pristine 1.98.0 上为 3 failed,且失败原因均为保留的冒号。
  3. 可优先尝试在共享文件名清洗 helper(get_s3_object_key() 所在的清洗逻辑)中加入 .replace(":", "_"),使 S3 logger 与冷存储 key 生成使用同一处理,保证上传与已存查找引用一致。
  4. 应用修改后,保持原测试不变重跑同一测试文件,确认结果从 3 failed 变为 3 passed。
  5. 不要修改原始 provider ID 与 JSON payload,不要改动批处理存储路由和已配置的目录前缀;冷存储 GET 请求继续按存储的 key 原样读取,包括历史上含冒号的 key。

验证方法

使用 Issue 中的参数化测试,对 s3://gs:// 和 ARN 三种 ID 断言生成文件名的最后一段不含冒号(assert ":" not in filename)。修复前应观察到 3 个用例全部失败,且失败均归因于保留的冒号;加入冒号替换后使用同一测试不做改动应全部通过。若下游 Hadoop/Databricks 读取不再抛出 Relative path in absolute URI,可进一步确认兼容性问题已消除。

参考来源

BerriAI/litellm #40234

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 25112

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注