Repository navigation
close: misleading "tenant isolation requires lease id" error when closing a session with no lease allocated #2016
Description
Summary
agent-device close --session <id> on a BrowserStack session where open was never successfully
called (no lease was ever allocated) fails with "tenant isolation requires lease id." — a message
that reads like a multi-tenancy/security enforcement failure, not "this session never allocated a
device, so there's nothing to close." It's confusing for exactly the case a caller is most likely to
hit it in: cleaning up after a connect that succeeded but a subsequent open failed before ever
reaching lease_allocate, or a caller that (correctly, per connect's own documented behavior)
never calls open at all in some code path.
Repro
export BROWSERSTACK_USERNAME=... BROWSERSTACK_ACCESS_KEY=...
agent-device connect browserstack \
--platform android --device "Google Pixel 8" --provider-os-version 14.0 \
--provider-app bs://<uploaded-apk> --force --json
# -> success, "leaseAllocated": false, "leasePreparation.status": "deferred"
# (connect never allocates a device -- confirmed via `agent-device help connect`)
agent-device close --session <session-id-from-above> --jsonActual
{
"success": false,
"error": {
"code": "INVALID_ARGS",
"message": "tenant isolation requires lease id.",
"hint": "Check command arguments and run --help for usage examples.",
"diagnosticId": "mt7nnlze-838148d3",
"logPath": "/Users/.../.agent-device/sessions/browserstack_adc-.../requests/....ndjson",
"diagnosticsRecord": { "session": "browserstack:adc-...", "requestId": "..." }
}
}Expected
An error that names the actual condition — something like "close: no lease was ever allocated on this session (open was never called or never reached lease_allocate) — nothing to close" — rather
than "tenant isolation," which reads as a cross-tenant access-control failure and sends a caller
looking in the wrong place (this cost real debugging time on our side before we confirmed it via the
CLI's own connect/open help text and a fresh repro, rather than a permissions/tenant-scoping bug).
The INVALID_ARGS code is also a mismatch — no argument was actually invalid; the session id was
correct and matched a real, live connected session. A dedicated code (e.g. NO_LEASE_ALLOCATED)
would let a caller branch on this programmatically instead of string-matching the message.
Suggested fix
- Detect this specific condition (
closecalled on a session withleaseAllocated: false) and
return a message that says so directly, with a distinct error code. - Since there's genuinely nothing to close in this state, consider making it a documented no-op
(success: true, changed: false) instead of an error at all —disconnectalready appears to
tolerate this shape of "nothing happened, that's fine" outcome;closecurrently doesn't.
Environment
agent-device0.20.10 (also present on 0.20.7 — not a regression, longstanding)- Node v22, macOS (darwin 25.x)
- BrowserStack App Automate, Android real device (Google Pixel 8 / 14.0)
- Confirmed the underlying "connect never allocates a device" model directly against
agent-device help connect/help open, not assumed:connect's own JSON response includes
"leaseAllocated": falseand"leasePreparation": {"status": "deferred", ...}every time.
Happy to share the full diagnostics log at logPath above if useful — redacted it from this report
since it includes local machine paths.
Activity
fix(daemon): require session===undefined for the close lease bypass, …
fix(daemon): close no longer throws tenant-isolation error on a never…