Skip to content

Upstream: SDK requestStream() discards results for 'failed' tasks #685

@jirispilka

Description

@jirispilka

Problem

The MCP SDK's requestStream() (@modelcontextprotocol/sdk/shared/protocol.js) only calls getTaskResult() for 'completed' tasks. For 'failed' tasks it yields a generic "Task X failed" error and discards the stored result entirely.

This forces us to store all task results as 'completed' even when they are errors — see res/task_status_workaround.md.

Three fixes needed in the SDK

1. Deliver results for 'failed' tasks

// Current:
if (task.status === 'failed') {
    yield { type: 'error', error: new McpError(ErrorCode.InternalError, `Task ${taskId} failed`) };
}

// Fix:
if (task.status === 'failed') {
    const result = await this.getTaskResult({ taskId }, resultSchema, options);
    yield { type: 'result', result };  // result has isError: true
}

2. Include statusMessage in the error (interim fix)

yield {
    type: 'error',
    error: new McpError(ErrorCode.InternalError, task.statusMessage || `Task ${taskId} failed`)
};

3. storeTaskResult() should accept an optional statusMessage

Our storeTaskResultWithMessage() calls updateTaskStatus('working', message) then storeTaskResult(status, result) — two non-atomic calls. The SDK should support this in one call.

Impact

Once fixed upstream, we can:

  • Store errors as 'failed' (semantically correct)
  • Remove the [error] prefix workaround from statusMessages
  • Remove storeTaskResultWithMessage() helper

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    t-aiIssues owned by the AI team.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions