OpenHands / OpenHands/software-agent-sdk
[Bug]: OpenHandsCloudWorkspace resume leaves the active client on stale connection data
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 539
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Bug Description
Cloud readiness polling refreshes _session_api_key and exposed URLs (openhands-workspace/openhands/workspace/cloud/workspace.py:361-374). Initial startup copies those values into inherited host/api_key and resets the remote client (:242-300). Public resume() polls readiness again (:444-458) but does not reapply the refreshed URL/key or reset the cached client.
After a sandbox returns with a rotated key or changed exposed URL, settings/skills calls can use the refreshed private key while normal workspace/conversation calls retain stale inherited headers and endpoint. The object can describe two different connections at once.
Expected Behavior
A RUNNING sandbox should have one atomic agent-server connection: endpoint, session key, inherited API key, and cached client must agree after startup and resume.
Actual Behavior
An independent, self-contained reproducer is posted in the issue comments. Save
it as /tmp/repro_4664.py, then run:
uv run python /tmp/repro_4664.py
On SDK commit bc5dfc50d, it exercises the real resume, readiness, and HTTP-client paths; only the external Cloud API and health-check boundaries are represented by a fixture and prints:
discovered_url=https://new-agent.example.com
active_host=https://old-agent.example.com
discovered_session_key=new-session-key
active_api_key=old-session-key
client_reused=True
client_base_url=https://old-agent.example.com
client_session_key=old-session-key
Suggested Implementation
Extract one private “apply ready connection” helper or immutable connection snapshot and use it after both initial readiness and resume. Apply host and api_key together, then reset/rebuild the client. Prefer the inherited API key as the single credential source once connected.
Acceptance Criteria
- Resume with a changed exposed URL routes subsequent calls to the new endpoint.
- Resume with a rotated session key sends the new
X-Session-API-Keyfor command, settings, and skills calls. - Initial provisioned/local modes and missing-key behavior remain unchanged.
- Cleanup clears one coherent connection state.
- Public workspace constructor and remote API contracts remain unchanged.
Version
Current main at 6d3881035. Existing issue search found no duplicate.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in openhands-workspace/openhands/workspace/cloud/workspace.py, especially the initial readiness flow at lines 242-300 and refresh logic at 361-374, then compare it with public resume() at 444-458. Run /tmp/repro_4664.py with uv to observe the stale host, key, and client. Done means startup and resume keep the endpoint, credentials, inherited fields, and cached client consistent while preserving the listed mode, cleanup, and API-contract behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100