Skip to content

Local desktop sessions get stuck against an undocumented legacy trajectory limit (3/3), unreachable via cancel_session()/list_sessions() #194

Description

@zach2940

Summary

Local desktop mode (hai_agents_local, the [desktop] extra) creates trajectories through what appears to be legacy infrastructure, reached via a server-side 307 redirect from the documented endpoint to an undocumented one. That legacy pool has its own small concurrency limit (3), and sessions stuck against it are not visible or cancellable through the modern sessions API (list_sessions(), cancel_session()), so a single crashed/killed local run can silently block all future local desktop sessions with no client-side way to recover.

Repro

  1. pip install "hai-agents[desktop]", set up a local-desktop agent per the docs (https://hub.hcompany.ai/computer-use-agents/desktop/local-control).
  2. Run several client.run_session(agent=<local-desktop agent>, messages=...) calls, including at least one that gets interrupted (killed process, crashed bridge, etc.) rather than completing cleanly.
  3. Eventually (in our case, after ~3 local sessions across a day of testing) every subsequent local desktop run_session()/start_session() call fails with:
    httpx.HTTPStatusError: Client error '429' for url 'https://agp.eu.hcompany.ai/api/v1/agents/surferh/trajectories'
    RuntimeError: local desktop bridge for environment '<env-id>' failed to start
    

What we found digging in

  • The client library (hai_agents_local/transport.py, CommandExchange.ensure_channel) POSTs to {base}/api/v1/trajectories/ — a normal, documented-looking path.
  • The server responds with a 307 redirect to /api/v1/agents/surferh/trajectories (confirmed directly with httpx, follow_redirects=False).
  • surferh is not a name that appears anywhere in the current hai-agents/hai_agents_local source — this looks like an internal routing detail pointing at legacy infrastructure (possibly related to the deprecated surfer-h-cli).
  • That endpoint is not present in the public OpenAPI spec (https://agp.hcompany.ai/share/openapi.json), so there's no documented way to list or manage what it's holding.
  • Direct POST to that endpoint returns:
    {"message":"Concurrent trajectory limit reached (3/3)","detail":[{"type":"too_many_requests","message":"Concurrent trajectory limit reached (3/3)"}]}
    with no Retry-After header.
  • Meanwhile, client.sessions.list_sessions() shows zero active/non-terminal sessions, and client.sessions.cancel_session(id=...) / hai sessions cancel <id> both report success on the sessions that are visible — none of it frees the legacy trajectory slot. We confirmed this is genuinely a separate pool, not a display lag: even with list_sessions() showing nothing active, the 429 persists.
  • The block appears to be account/org-level, not tied to a specific API key — regenerating the key didn't clear it.
  • In our case it eventually cleared on its own after roughly 30-40 minutes of inactivity, but we couldn't find any documented timeout to confirm that's expected/reliable behavior rather than coincidence.

Impact

Any crashed or force-killed local desktop session can silently exhaust the entire local desktop concurrency budget for the account, with no visibility into it (doesn't show in list_sessions()) and no way to clear it (cancel_session() doesn't reach it). This happened to us repeatedly over the course of a single day of normal development/testing.

Ask

  • A documented way to list/cancel whatever's held in this legacy pool (or route local desktop trajectory creation through the same lifecycle as sessions, so cancel_session()/list_sessions() actually reach it).
  • Alternatively, if this is intentional legacy infra that's expected to be phased out, a heads-up in the local desktop docs (https://hub.hcompany.ai/computer-use-agents/desktop/local-control) about the separate concurrency pool and how to recover from it would save the next person the multi-hour debugging session this took us.

Happy to share full session IDs / timestamps / account details privately if useful — didn't want to post them in a public issue.


Environment: hai-agents 1.0.6 (the current/latest version per PyPI at time of writing), macOS, EU region (agp.eu.hcompany.ai), Python 3.14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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