Repository navigation
[Bug]: AgentDevice startup failures are hidden behind a 30-second timeout #18500
Description
Before submitting
- Searched existing issues and PRs; no duplicate found for agent daemon startup errors being replaced with the readiness timeout.
- Included an isolated reproduction and the underlying CLI error.
Area
apps/server
Steps to reproduce
- Use a separate T3 home with a legacy JSON file at
userdata/device/agent-device/daemon.lockand nodaemon.json. Do not modify an active T3 home. A synthetic JSON file is sufficient to reproduce the newer CLI's lock-format rejection. - Enable Device support and agent device access, then call
device_open. - Compare the error with the exact installed AgentDevice CLI in the same isolated state directory:
diagnostic_state="$(mktemp -d)"
printf '%s\n' '{"pid":99999999,"processStartTime":"Fri Oct 9 01:34:33 2026"}' > "$diagnostic_state/daemon.lock"
AGENT_DEVICE_STATE_DIR="$diagnostic_state" \
AGENT_DEVICE_DAEMON_SERVER_MODE=http \
AGENT_DEVICE_DAEMON_IDLE_TIMEOUT_MS=0 \
AGENT_DEVICE_NO_UPDATE_NOTIFIER=1 \
node ~/.t3/tools/agent-device/0.21.24/node_modules/agent-device/dist/src/cli.js devices --jsonExpected behavior
When the CLI fails without registering a daemon, T3 should promptly report the startup failure and useful recovery guidance, retaining the underlying diagnostics. It should preserve the lock for deliberate manual repair.
Actual behavior
The CLI exits immediately with code 1 and this error:
{
"code": "COMMAND_FAILED",
"message": "Daemon registration ownership could not be verified.",
"details": {
"reason": "daemon_registration_unproven",
"inspection": { "state": "unproven", "reason": "non-directory" }
}
}LocalDeviceHost.startAgentDeviceDaemon ignores the CLI result and execution errors, then waits for an absent daemon.json. device_open instead reports Agent tools did not start within 30000 ms. The Device panel also loses the actionable cause.
Impact
Major degradation: agent automation was unavailable while the emulator preview stream continued working. A full reboot did not change the failure. The timeout suggests a slow startup and conceals the retained legacy lock.
Version or commit
T3 investigation baseline: c0c495e4dc12bbb0bb44387657a5682661cdd05c. The masking behavior also existed in the original Device support implementation.
T3 upgraded AgentDevice from 0.21.12 to 0.21.23 in #17566, then to 0.21.24 in #17706. The repository's current 0.21.25 pin still rejects non-directory lock state.
Environment and evidence
macOS, Android Emulator, expo-device-hub 0.15.3, AgentDevice 0.21.24 in HTTP daemon mode.
- The exact installed CLI started successfully against fresh isolated state.
- Copying only the legacy lock into a second isolated directory produced the failure above. The lock remained a file and no
daemon.jsonappeared. - Published AgentDevice
0.21.12creates a JSON lock file; the later versions inspect a lock directory with an owner record. - Upstream intentionally retains and refuses legacy locks: AgentDevice #3125, with the concurrency/migration boundary described in #3122.
Workaround
After manually confirming that the recorded process no longer exists and no daemon is registered, the stale legacy file can be backed up as a deliberate maintenance action. This report does not propose automatic deletion, and live recovery is separate from the diagnostics fix.
Activity
juliusmarminge commentedon Oct 12, 2026
Note
Grok responding on behalf of Julius.
Confirmed on main (
19bef8c1): this is a T3 error-surfacing bug. The legacy lock rejection itself is not.LocalDeviceHost.startAgentDeviceDaemonrunsagent-device devices --jsonwithEffect.ignore, which drops the exit code, stdout/stderr and spawn errors. It then polls fordaemon.jsonfor anotherDAEMON_READY_TIMEOUT_MS.DeviceServiceturns the timeout into the genericAgent tools did not start within 30000 ms.daemon.lockfile is intentional upstream behavior (fix: bind daemon registration writes to the acquired owner callstack/agent-device#3125). It only affects state directories created by AgentDevice ≤0.21.12, before fix(devices): recover stalled video without losing simulator input #17566. T3 won't auto-delete the lock.Workaround: stop T3, confirm no
agent-deviceprocess is running, then moveuserdata/device/agent-device/daemon.lockaside and reopen the device.Fix scope: when the CLI exits non-zero before
daemon.jsonappears, fail right away and surface its JSONmessage/reason. Not related to #18182/#18301 (theELECTRON_RUN_AS_NODEissue).