| name | langfuse-upgrade-migration |
| description | Upgrade Langfuse SDK versions and migrate between API changes.
Use when upgrading Langfuse SDK, handling breaking changes,
or migrating between Langfuse versions.
Trigger with phrases like "upgrade langfuse", "langfuse migration",
"update langfuse SDK", "langfuse breaking changes", "langfuse version".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Bash(pip:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Langfuse Upgrade & Migration
Overview
Guide for upgrading Langfuse SDK versions and handling breaking changes.
Prerequisites
- Existing Langfuse integration
- Access to test environment
- Version control (git)
Instructions
Step 1: Check Current Version and Updates
npm list langfuse
npm outdated langfuse
pip show langfuse
pip index versions langfuse
open https://github.com/langfuse/langfuse-js/releases
open https://github.com/langfuse/langfuse-python/releases
Step 2: Review Breaking Changes
## Common Breaking Changes by Version
### v2.x -> v3.x (TypeScript)
- `Langfuse.trace()` returns `Trace` instead of `Promise<Trace>`
- `flushAsync()` replaces `flush()` (now async)
- `observeOpenAI()` moved to main package export
- Generation `completionTokens` -> `completionTokens` (was `completion_tokens`)
### v1.x -> v2.x (Python)
- `langfuse.trace()` now returns synchronously
- Decorator `@observe()` replaces `@langfuse.observe()`
- `flush()` is now synchronous, use `shutdown()` for cleanup
Step 3: Update SDK with Testing
git checkout -b chore/upgrade-langfuse
npm install langfuse@latest
pip install --upgrade langfuse
npm test
pytest
npm install langfuse@3.0.0
Step 4: Handle TypeScript API Changes
import Langfuse from "langfuse";
const langfuse = new Langfuse({
publicKey: "...",
secretKey: "...",
});
const trace = await langfuse.trace({ name: "test" });
await langfuse.flush();
import { Langfuse } from "langfuse";
const langfuse = new Langfuse({
publicKey: "...",
secretKey: "...",
});
const trace = langfuse.trace({ name: "test" });
await langfuse.flushAsync();
Step 5: Handle Python API Changes
from langfuse import Langfuse
langfuse = Langfuse()
@langfuse.observe()
def my_function():
pass
langfuse.flush()
from langfuse import Langfuse
from langfuse.decorators import observe, langfuse_context
langfuse = Langfuse()
@observe()
def my_function():
langfuse_context.update_current_observation(
metadata={"key": "value"}
)
pass
langfuse.flush()
Step 6: Migration Script for Codemod
import { Project } from "ts-morph";
const project = new Project({
tsConfigFilePath: "./tsconfig.json",
});
const sourceFiles = project.getSourceFiles();
for (const sourceFile of sourceFiles) {
let modified = false;
const importDeclarations = sourceFile.getImportDeclarations();
for (const importDecl of importDeclarations) {
if (importDecl.getModuleSpecifierValue() === "langfuse") {
const defaultImport = importDecl.getDefaultImport();
if (defaultImport?.getText() === "Langfuse") {
importDecl.removeDefaultImport();
importDecl.addNamedImport("Langfuse");
modified = true;
}
}
}
sourceFile.forEachDescendant((node) => {
if (
node.getKindName() === "CallExpression" &&
node.getText().includes()
) {
node
.(ts..)
?.()
.(
node
.()
.(, )
);
modified = ;
}
});
(modified) {
.();
sourceFile.();
}
}
Step 7: Test Migration
import { describe, it, expect, beforeAll, afterAll } from "vitest";
import { Langfuse } from "langfuse";
describe("Langfuse Migration Tests", () => {
let langfuse: Langfuse;
beforeAll(() => {
langfuse = new Langfuse({
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
secretKey: process.env.LANGFUSE_SECRET_KEY!,
});
});
afterAll(async () => {
await langfuse.shutdownAsync();
});
it("should create trace with new API", () => {
const trace = langfuse.trace({
name: "migration-test",
metadata: { version: "3.x" },
});
expect(trace).toBeDefined();
expect(trace.id).toBeDefined();
});
it("should create generation with correct usage format", () => {
const trace = langfuse.trace({ : });
generation = trace.({
: ,
: ,
: [{ : , : }],
});
generation.({
: ,
: {
: ,
: ,
},
});
(generation.).();
});
(, () => {
langfuse.({ : });
(langfuse.())...();
});
});
Output
- Updated SDK to latest version
- Migrated deprecated API calls
- All tests passing
- No breaking changes in functionality
Version Compatibility Matrix
| Feature | v2.x | v3.x | Migration |
|---|
| Default import | import Langfuse | import { Langfuse } | Update imports |
trace() return | Promise<Trace> | Trace | Remove await |
flush() | Sync | N/A | Use flushAsync() |
| Usage keys | snake_case | camelCase | Update all usage objects |
Error Handling
| Error | Cause | Solution |
|---|
| Import error | Changed export | Use named import |
| Type error on usage | Key name change | Use camelCase keys |
| flush() not found | Method renamed | Use flushAsync() |
| Decorator error | New import path | Import from langfuse.decorators |
Rollback Plan
git checkout main
npm install langfuse@2.0.0
git checkout HEAD -- package-lock.json
npm ci
Resources
Next Steps
For CI/CD integration, see langfuse-ci-integration.