自托管 Langfuse 2.50 接 SDK 打 score,接口返回 422,原文 trace_id must be a valid uuid,但 trace 列表里能看到这条记录,id 是 32 位不带横线的十六进制,SDK 版本是 2.50.0。

一开始怀疑是「打分时 trace 还没 flush,服务端查不到」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。SDK 版本与 server 的 score schema 不一致。另一种情况是trace_id 用了自定义字符串,不是 W3C 的 32 位 hex。

还有一种情况,公钥私钥配到了另一个 project,id 空间不同。

动手时先用 curl 直接调 score 接口看返回

curl -s -X POST http://localhost:3000/api/public/scores -H 'Authorization: Basic $LANGFUSE_AUTH' -H 'Content-Type: application/json' -d '{"traceId":"abc","name":"qa","value":1}'

再往下把 trace_id 统一成 32 位小写 hex

python -c "import uuid;print(uuid.uuid4().hex)"

接着打分前先 flush 一次客户端缓冲

python -c "from langfuse import Langfuse;Langfuse().flush()"

剩下的就是确认项目密钥对应的 project id

python -c "import os;print(os.getenv('LANGFUSE_HOST'), os.getenv('LANGFUSE_PUBLIC_KEY')[:8])"

当时还开着另一个排查窗口,两边日志对照着看才定位到。

改完先别撤,确认这几项。score 写入返回 200,Langfuse 页面上该 trace 出现评分,过滤 project 后也能查到,日志里不再有 422。

这里还有个坑。score 的 trace 校验比 trace 上报严格,id 格式不对会直接拒绝;自定义追踪系统接入时要在边界处转成标准 hex,不要用业务单号当 trace_id。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189