Skip to content

Commit 85f0c79

Browse files
raphaeltmclaude
andcommitted
fix: use node-scoped callback token when waking restored container
wakeFromSnapshot launched the restored container with a workspace-scoped callback token (signCallbackToken) passed as the container CALLBACK_TOKEN, but the vm-agent uses it for node callbacks (error/activity/message reporting) which reject workspace-scoped tokens with 403 "Insufficient token scope". Restored sessions therefore accepted a prompt (200) but silently failed to report the agent's reply, so no answer appeared after wake. Sign a node-scoped token (signNodeCallbackToken) to match the initial launch in launchInstantSession. Diagnosed from staging Worker logs (node_auth.rejected_workspace_scoped_token). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ac6a9e8 commit 85f0c79

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

apps/api/src/durable-objects/vm-agent-container.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { drizzle } from 'drizzle-orm/d1';
55
import * as schema from '../db/schema';
66
import type { Env } from '../env';
77
import { log } from '../lib/logger';
8-
import { signCallbackToken, signNodeManagementToken } from '../services/jwt';
8+
import { signNodeCallbackToken, signNodeManagementToken } from '../services/jwt';
99

1010
export const DEFAULT_CF_CONTAINER_SLEEP_AFTER = '1h';
1111
export const DEFAULT_CF_CONTAINER_ACTIVE_WORK_MAX_MS = 2 * 60 * 60 * 1000;
@@ -345,7 +345,13 @@ export class VmAgentContainer extends Container<Env> {
345345
});
346346

347347
await this.ctx.storage.put('lifecycleStatus', 'launching' satisfies LifecycleStatus);
348-
const callbackToken = await signCallbackToken(config.workspaceId, this.env);
348+
// The container's CALLBACK_TOKEN must be node-scoped to match the initial
349+
// launch (see launchInstantSession): the vm-agent uses it for node callbacks
350+
// (error/activity/message reporting) which reject workspace-scoped tokens.
351+
// Using a workspace-scoped token here caused restored sessions to accept a
352+
// prompt (200) but silently fail to report the agent's reply back (403
353+
// "Insufficient token scope"), so no answer appeared after wake.
354+
const callbackToken = await signNodeCallbackToken(config.nodeId, this.env);
349355
await this.launch(config, { nodeCallbackToken: callbackToken });
350356

351357
const { token } = await signNodeManagementToken(workspace.userId, config.nodeId, config.workspaceId, this.env);

0 commit comments

Comments
 (0)