Troubleshooting
Session created before connection
Create the Tasks session after the SDK client connects:
await client.connect(transport);
const session = createTaskSessionFromClient(client, { endpointId });Create a new Tasks session when replacing or reconnecting the SDK client.
Adapter already active for this Client
One SDK Client can have one active Tasks session. Close the current session before creating another:
await session.close();
const nextSession = createTaskSessionFromClient(client, { endpointId });V2 requires raw dispatch
Pass the host request coordinator and initialization framing together:
const session = createTaskSessionFromClient(client, {
endpointId,
rawDispatch: hostRequestCoordinator.dispatch,
v2RequestFraming: { protocolVersion, clientInfo, clientCapabilities },
});See Adapters and schemas.
Failed and cancelled outcomes do not throw
result() and settle() return terminal outcomes:
const { outcome } = await execution.settle();
if (outcome.status === "completed") useResult(outcome.result);
if (outcome.status === "failed") reportTaskFailure(outcome.error);
if (outcome.status === "cancelled") reportCancellation();Use resultFromTaskOutcome(outcome) for result-or-throw handling.
Input callback context is missing
Pass application context with the call:
await session.callTool("review", input, {
applicationContext: { requestId: "request-42" },
});Read it from context.applicationContext in the input callback. See Input and recovery.
Task updates already acquired
execution.updates() has one consumer. Fan out events inside the application, or use onEvent with execution.settle().
Recovery fails
Create the session with the same endpointId used by the source execution, then resume the stored reference:
const recovered = await session.resumeTask(await taskStore.load());An unknown task has expired or was removed by the server. TaskRecoveryOwnershipError means the task already has an active local owner (a live execution or controller for the same task identity); endpoint, generation, and unsupported-operation mismatches reject with ordinary Errors naming the mismatch.
Use execution.handoff((reference) => taskStore.save(reference)) when transferring a live task to durable storage.
Cancellation and detachment
See Cancellation and detachment. An AbortSignal stops local waiting; cancel() requests remote cancellation.
Task execution unsupported
Check session.capabilities.execution and the tool declaration. Use task.preference: "allow" to accept an immediate result, or "require" to require task-backed execution.
2025-11-25 receiver capacity or expiry
Configure maxTasks and ttlMs:
const receiver = bindTaskReceiver(client, {
methods: { "sampling/createMessage": true },
sampling: handleSampling,
maxTasks: 100,
ttlMs: 60_000,
});At capacity, new task creation is rejected. After TTL expiry, the task is no longer retained.
Request timeout missing from follow-up requests
Set request context on the tool call:
const execution = await session.callTool("generate_report", input, {
requestTimeoutMs: 15_000,
headers: { authorization: `Bearer ${token}` },
});The session applies these options to the initial call and task follow-up requests.