Skip to content

agent-device sharding with no --device fails: the front rewrites --device to the UDID #971

Closed

Description

@V3RON

What happened

The slow-lane case in e2e/slow-agent-device.test.ts (iOS, "with the device limit raised to 2 > with both devices booted, agent A holding one and agent B the other: A's test --shard-all 1 with no --device passes, and A's test --shard-all 2 with no --device fails with test sharding requires 2 devices, but only 1 matched") fails on origin/main (3de46d1). It fails on the --shard-all 1 step:

INVALID_ARGS: Session "…" is already bound to apple device "simlock-<uuid>" (<UDID>), but this request selected --device=<UDID>

Command: scripts/slow-e2e.sh e2e/slow-agent-device.test.ts -t "shard-all 1 with no --device passes" --bail=1, with agent-device 0.21.28. Log on the slow-lane Mac: /var/folders/tb/j39z273s5kn7lb9tz1dhk8l00000gn/T/simlock-slow-e2e-20261023-234115.log.

Expected

--shard-all 1 with no --device runs on the agent's one leased device.

Likely cause (not confirmed)

ruleSharding in src/agent-device/front/request-rules.ts:256-261 rewrites --device to the device's name when the open reply carried one, and to its address (UDID) otherwise. replyFacts in src/agent-device/front/allocate.ts:419 keeps the name only when agent-device's open reply has data.device.name. In this run the rewrite used the UDID, and agent-device refuses a UDID against a session it bound by name.

Found during the #957 delivery (PR #967), which does not touch this path.

Written by an agent.

Activity

  1. added
    bug:newReported. An agent may triage it (rule 8), and nothing more.
    on Oct 23, 2026
  2. removed
    bug:newReported. An agent may triage it (rule 8), and nothing more.
    on Oct 24, 2026
  3. self-assigned this
    on Oct 24, 2026
  4. V3RON commented on Oct 24, 2026

    @V3RON
    ContributorAuthor

    Reproduction

    Confirmed, without devices. Branch bug/971-repro, src/agent-device/edge.test.ts, "rule 7, sharding": "test --shard-all with no --device names each of the token's leased devices by the name agent-device's inventory gives it when the allocate reply named no device, for an agent holding one device and one holding two".

    pnpm exec vitest run --project unit src/agent-device/edge.test.ts -t "inventory gives it"
    
    AssertionError: expected 'fake-ios-1-addr-1' to be 'simlock-aaaa'
     ❯ src/agent-device/edge.test.ts:3994  expect(flagsOf(one)["device"]).toBe("simlock-aaaa");
    

    Root cause

    Defect. The issue's guess is right, and it hits every run. replyFacts (src/agent-device/front/allocate.ts:419) takes the name from data.device.name. agent-device's allocate reply never has that field, so name is always undefined. ruleSharding (src/agent-device/front/request-rules.ts:257-260) then falls back to the UDID. agent-device checks --device against the session's device by name only, so it refuses the UDID. The unit tests missed it because FakeAgentDevice (src/agent-device/testing.ts:524-527) adds device: { id, name } to every allocate reply.

    # agent-device v0.21.28 (main is the same)
    packages/daemon/src/sessions/handlers/lease.ts   data: { lease: allocated, ...(providerData ? { provider } : {}) }
    dist/src/sdk-device.js (installed 0.21.28)       function Y(e,t){return X(e.name)===X(t)}   // --device vs bound session: name only
    packages/replay-port/.../session-test-shard-devices.ts   device.id === selector || name match  // shard lookup takes either
    

    Simplest fix

    When an allocate reply names no device, the front calls agent-device devices once on that lease (its udid/serial) and stores the entry's name in the front map. The fake's default allocate reply drops device, as agent-device does.

    Alternatives rejected

    • Send --udid/--serial instead of --device: the shard lookup reads only --device, so with no list it picks any booted device, including another agent's.
    • Have simlock's driver report the simulator name: that copies agent-device's naming, and Android emulators get no name this way.
    • Ask agent-device to put the device in its allocate reply: this needs an upstream release, and the bug stays until then.

    Risk

    • The existing test "names a device … by its id when … the reply named none" (edge.test.ts:3962) pins the bug and must change.
    • Allocate gains one devices call; through a gateway it must reach the lease's worker.
    • ruleDevice/ruleShardList (namesDevice, request-rules.ts:176) also refuse an agent that names its own device by its agent-device name. The same fix covers that.

    Written by an agent.

  5. removed their assignment
    on Oct 24, 2026
  6. V3RON commented on Oct 25, 2026

    @V3RON
    ContributorAuthor

    Decision

    Maintainer: fix it on the simlock side now. Once per lease, the agent-device front reads agent-device's device list and takes the leased device's name, so ruleSharding rewrites --device to the name (simlock-<uuid>, unique per device) instead of the UDID. The test fake's allocate reply (testing.ts:524-527) is fixed to match the real one.

    Later, an agent-device change: accept the bound device's UDID as --device (tracked in agent-device).

    Written by an agent.

  7. added
    bug:readyAn agent may fix it.
    and removed on Oct 25, 2026
  8. V3RON commented on Oct 25, 2026

    @V3RON
    ContributorAuthor

    agent-device side: callstack/agent-device#3945.

  9. self-assigned this
    on Oct 25, 2026
  10. added a commit that references this issue on Oct 25, 2026
    78b9238
  11. V3RON commented on Oct 25, 2026

    @V3RON
    ContributorAuthor

    Delivery run

    Merged: #986 (#971)
    Parked: none
    Waiting: none
    Decided: #971 — when to read the device list → lazily, once per lease, the first time a request rule needs the name (Assumption in PR #986)

    Written by an agent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bug:readyAn agent may fix it.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions