
bug: startActiveObservation with asType does not write observation type to span unless .update() is called
快速结论:该问题发生在使用 Langfuse JavaScript SDK 的 startActiveObservation 方法并设置 asType 参数时,观察类型属性未正确写入 OpenTelemetry span,导致观察在 Langfuse 界面显示为通用的 SPAN 而非指定类型。优先排查是否在回调中调用了 .update({}) 作为临时解决方法。
问题场景
用户在使用 @langfuse/tracing SDK(版本约 5.3.0)时,通过 startActiveObservation 创建观察(observation),并指定 asType 为 "chain"、"retriever" 或 "embedding" 等类型。问题仅影响 startActiveObservation,而 startObservation 不受影响。
报错原文
startActiveObservation("my-retriever", async () => {
// do work — never call obs.update()
}, { asType: "retriever" });
// → appears as SPAN in Langfuse, not RETRIEVER
原因分析
在 LangfuseBaseObservation 构造函数中,createObservationAttributes(负责写入 OBSERVATION_TYPE 属性)仅在 params.attributes 存在时被调用:
if (params.attributes) {
this.otelSpan.setAttributes(
createObservationAttributes(params.type, params.attributes)
);
}
而 startActiveObservation 创建指定类型的观察时未传递 attributes 参数:
case "chain":
observation = new LangfuseChain({ otelSpan: span });
break;
case "retriever":
observation = new LangfuseRetriever({ otelSpan: span });
break;
因此 params.attributes 始终为 undefined,条件判断失败,导致类型属性从未写入 span。类型仅在用户手动调用 .update() 时才被写入,但这不是文档中要求的操作,且失败时无任何告警。
环境排查
- 确认 SDK 版本:
@langfuse/tracing和@langfuse/otel是否为 v5.3.0 或更新版本(问题在 v5.3.0 中确认存在) - 确认 OpenTelemetry 集成版本:
@opentelemetry/sdk-node约 v0.218.0 - 确认是否使用 Langfuse Cloud(问题在 Cloud 版本中报告)
- 确认是否存在其他自定义
attributes传递——如果传递了 attributes,类型属性可能意外正确写入
解决步骤
- 临时解决方法(已验证有效):在回调函数的第一行显式调用
obs.update({}),强制写入类型属性:startActiveObservation("my-retriever", async (obs) => { obs.update({}); // do work }, { asType: "retriever" }); - 官方修复:该问题已在
langfuse/langfuse-js#836中修复,预计在后续版本中发布。修复方法是在LangfuseBaseObservation构造函数中无条件调用createObservationAttributes,将params.attributes ?? {}作为参数传递。 - 升级 SDK:当新版本发布后,升级
@langfuse/tracing到包含修复的版本(可关注 v5.3.1 或更高版本)。 - 检查调用方式:如果无法升级,检查代码中所有
startActiveObservation调用,确保在回调中尽早调用.update()或传递attributes参数。
验证方法
在 Langfuse 界面查看对应观察的类型列:如果修复成功,观察应显示为指定的类型(如 RETRIEVER、CHAIN 等),而非通用的 SPAN。也可以通过 OpenTelemetry 导出器直接检查 span 属性,确认 langfuse.observation.type 属性是否已正确设置。



