Skip to content

Fix asyncio event loop conflicts in CdpEvmWalletProvider#968

Open
darrylsj wants to merge 1 commit intocoinbase:mainfrom
darrylsj:fix-asyncio-event-loop
Open

Fix asyncio event loop conflicts in CdpEvmWalletProvider#968
darrylsj wants to merge 1 commit intocoinbase:mainfrom
darrylsj:fix-asyncio-event-loop

Conversation

@darrylsj
Copy link

Problem

Fixes #967

The CdpEvmWalletProvider.__init__ method was using asyncio.run() which fails when an asyncio event loop is already running (common in Jupyter notebooks, web frameworks, and agent orchestration systems). This resulted in misleading "NetworkError(ETIMEDOUT, 'Request timed out')" errors when the real issue was asyncio event loop conflicts.

Solution

  1. Replaced direct asyncio.run() calls in __init__ with the _run_async() helper method for consistency
  2. Enhanced _run_async() method to properly detect and handle existing event loops:
    • Uses asyncio.get_running_loop() to detect if we're in an existing event loop
    • If there's an existing loop, runs the coroutine in a separate thread with its own event loop
    • If no existing loop, creates a new one safely
    • Properly cleans up event loops to prevent resource leaks

Changes Made

  • File: coinbase_agentkit/wallet_providers/cdp_evm_wallet_provider.py
  • Lines 62-66: Replace asyncio.run() with _run_async()
  • Lines 345-357: Complete rewrite of _run_async() method with proper event loop handling

Benefits

  • ✅ Works seamlessly in Jupyter notebooks
  • ✅ Compatible with FastAPI, Flask, and other web frameworks
  • ✅ Works in agent orchestration systems (OpenClaw, etc.)
  • ✅ Provides accurate error messages instead of misleading timeouts
  • ✅ Maintains backward compatibility with non-event-loop environments
  • ✅ Proper resource cleanup prevents memory leaks

Testing

The fix has been tested to ensure:

  • Existing functionality remains unchanged in normal environments
  • Compatibility with environments that have running event loops
  • Proper error propagation without misleading timeout messages
  • No resource leaks from unclosed event loops

Note on Error Messages

This also addresses the misleading error message issue where asyncio conflicts were being reported as network timeouts. The new implementation allows the actual asyncio errors to propagate properly when they occur, making debugging much easier.

Dependencies

No new dependencies required - uses Python's built-in concurrent.futures and threading modules.

- Replace asyncio.run() calls in __init__ with _run_async() helper
- Improve _run_async() to detect existing event loops and handle them properly
- Run coroutines in separate thread when event loop already exists
- Prevents misleading ETIMEDOUT errors when real issue is asyncio conflict
- Fixes compatibility with Jupyter notebooks, web frameworks, and agent systems

Fixes coinbase#967
@cb-heimdall
Copy link

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 1
Sum 2

@github-actions github-actions bot added wallet provider New wallet provider python labels Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python wallet provider New wallet provider

Development

Successfully merging this pull request may close these issues.

CdpEvmWalletProvider fails with misleading ETIMEDOUT when asyncio event loop exists

2 participants