-
Notifications
You must be signed in to change notification settings - Fork 709
fix: make transport Start() idempotent to resolve issue #583 #606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This fix addresses the bug where calling client.Start() after creating a transport with transport.NewStdioWithOptions() would cause client.Initialize() to fail with 'transport error: stdio client not started'. Root cause: PR #564 modified client.Start() to skip starting *transport.Stdio transports based on type checking. This worked for transports created via NewStdioMCPClientWithOptions() (which pre-starts the transport), but failed for transports created directly with transport.NewStdioWithOptions(). Solution: Made Start() idempotent across all transport types instead of type-checking. Calling Start() multiple times is now safe with no side effects after the first call. Changes: - Stdio: Added started flag; returns nil on subsequent calls - SSE: Changed to return nil instead of error when already started - StreamableHTTP: Added early return check using initialized channel - InProcess: Added started flag; returns nil on subsequent calls - Client: Removed type-checking hack; always calls transport.Start() The started flag is reset on failure to allow retry. Breaking changes: None - fully backward compatible. Tests added: - TestDirectTransportCreation: Tests exact bug scenario from #583 - TestNewStdioMCPClientWithOptions: Verifies backward compatibility - TestMultipleClientStartCalls: Tests client-level idempotency - TestStdio_StartIdempotency: Tests multiple Start() calls - TestStdio_StartFailureReset: Tests failed Start() retry - Transport-specific idempotency tests for all transport types Fixes #583
WalkthroughMakes Start idempotent across client and transports. client.Start always calls transport.Start. In-process, stdio, SSE, and StreamableHTTP transports now guard repeated Start calls. Adds tests for stdio and transport idempotency and a regression test for issue #583 validating stdio initialization via options. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (8)
🧰 Additional context used🧠 Learnings (1)📚 Learning: 2025-08-14T16:35:34.100ZApplied to files:
🧬 Code graph analysis (4)client/transport/inprocess.go (1)
client/issue583_test.go (4)
client/transport/idempotent_all_transports_test.go (2)
client/transport/stdio_idempotent_test.go (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🔇 Additional comments (17)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Merging this branch changes the coverage (1 decrease, 1 increase)
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
Description
Fixes #583 by making
Start()idempotent across all transport types. The bug causedclient.Initialize()to fail with "transport error: stdio client not started" when using the direct transport creation pattern withtransport.NewStdioWithOptions().Root cause: PR #564 modified
client.Start()to skip starting*transport.Stdiotransports based on type checking. This worked forNewStdioMCPClientWithOptions()(which pre-starts the transport), but failed for directtransport.NewStdioWithOptions()usage.Solution: Made
Start()idempotent across all transport types instead of type-checking. MultipleStart()calls are now safe with no side effects.Fixes #583
Type of Change
Checklist
Changes Made
startedflag; returnsnilon subsequent callsnilinstead of error when already startedinitializedchannelstartedflag; returnsnilon subsequent callstransport.Start()The
startedflag is reset on failure to allow retry.Tests Added
Regression Tests (client/issue583_test.go)
TestDirectTransportCreation: Tests exact bug scenario from bug: client.Intialize errors when using transport.NewStdioWithOptions #583TestNewStdioMCPClientWithOptions: Verifies backward compatibilityTestMultipleClientStartCalls: Tests client-level idempotencyIdempotency Tests (client/transport/stdio_idempotent_test.go)
TestStdio_StartIdempotency: Tests multipleStart()callsTestStdio_StartFailureReset: Tests failedStart()retryTestStdio_StartWithOptions_Idempotent: Tests with custom optionsTransport Tests (client/transport/idempotent_all_transports_test.go)
TestStreamableHTTP_StartIdempotencyTestInProcessTransport_StartIdempotencyTestInProcessTransport_StartFailureResetAdditional Information
Backward Compatibility: Fully backward compatible - no interface changes, no new public APIs. Existing code continues to work, with the added benefit that
Start()can now be called multiple times safely.Test Results: All existing tests pass (72+ tests). New tests verify the fix and prevent regression.
Usage Example:
Summary by CodeRabbit
Bug Fixes
Tests