diff --git a/src/session.ts b/src/session.ts index 4772af9..3c9d5d6 100644 --- a/src/session.ts +++ b/src/session.ts @@ -179,8 +179,10 @@ export class Session implements AsyncDisposable { } } - sessionLog("init", "ERROR: transport closed before init message received"); - throw new Error("Failed to initialize session - no init message received"); + const stderr = this.transport.getStderr(); + const detail = stderr ? `\nCLI stderr:\n${stderr}` : ''; + sessionLog("init", `ERROR: transport closed before init message received${detail}`); + throw new Error(`Failed to initialize session - no init message received${detail}`); } /** diff --git a/src/transport.ts b/src/transport.ts index a3d0f03..1e7351f 100644 --- a/src/transport.ts +++ b/src/transport.ts @@ -198,6 +198,7 @@ export class SubprocessTransport { private agentId?: string; private wireMessageCount = 0; private lastMessageAt = 0; + private stderrLines: string[] = []; constructor( private options: InternalSessionOptions = {} @@ -247,11 +248,13 @@ export class SubprocessTransport { }); // Log stderr for debugging (CLI errors, auth failures, etc.) + // Also buffer lines so session.initialize() can include them in errors. if (this.process.stderr) { this.process.stderr.on("data", (data: Buffer) => { const msg = data.toString().trim(); if (msg) { console.error("[letta-code-sdk] CLI stderr:", msg); + this.stderrLines.push(msg); } }); } @@ -356,6 +359,11 @@ export class SubprocessTransport { return this.closed; } + /** Return buffered stderr output from the CLI subprocess. */ + getStderr(): string { + return this.stderrLines.join("\n"); + } + private handleMessage(msg: WireMessage): void { this.wireMessageCount++; this.lastMessageAt = Date.now();