Summary
With a proxy lease, every iOS install and open on a remote connection is refused with:
Error (INVALID_ARGS): Active remote connection is already bound to a different platform. Re-run connect --force to replace it.
even though the connection was opened for iOS and the request targets that same iOS device. Android is unaffected.
Cause
When the lease state resolves a device, applyResolvedDeviceSelector copies the device's internal platform into the request flags:
|
function applyResolvedDeviceSelector(flags: CliFlags, device: DeviceInfo): void { |
|
flags.platform = device.platform; |
|
flags.target = device.target ?? flags.target; |
|
if (isIosFamily(device)) { |
|
flags.udid = device.id; |
|
return; |
|
} |
|
if (device.platform === 'android' || device.platform === 'harmonyos') { |
|
flags.serial = device.id; |
|
} |
|
} |
For an iOS-family device that value is the internal apple, not the public ios. assertRequestedConnectionScope then compares it with the connection's stored public platform:
|
if (state.platform && flags.platform && state.platform !== flags.platform) { |
|
throw new AppError( |
|
'INVALID_ARGS', |
|
'Active remote connection is already bound to a different platform. Re-run connect --force to replace it.', |
|
{ session: state.session, platform: state.platform }, |
|
); |
|
} |
so ios !== apple and the request is refused. Android passes because its internal and public names are both android.
Repro
agent-device 0.21.12 (same code on main at 76dbee0): open a remote connection with platform: ios and a proxy lease, then run install <app> (or open) against the leased device. It fails right after the device lookup, before a lease is taken.
Possible fix
Store the public name in the flags, e.g. flags.platform = publicPlatformString(device) (already used by buildProxyDeviceKey in the same file), or normalize both sides before the comparison.
Context
Found through Stim (appandflow/stim#1096). Stim works around it by keeping iOS on the default 60 s lease (appandflow/stim#1127), which means large iOS apps can still hit #2946 (lease not renewed during upload); fixing this would let iOS use the longer proxy lease.
Summary
With a proxy lease, every iOS
installandopenon a remote connection is refused with:even though the connection was opened for iOS and the request targets that same iOS device. Android is unaffected.
Cause
When the lease state resolves a device,
applyResolvedDeviceSelectorcopies the device's internal platform into the request flags:agent-device/src/cli/commands/connection-runtime.ts
Lines 888 to 898 in 76dbee0
For an iOS-family device that value is the internal
apple, not the publicios.assertRequestedConnectionScopethen compares it with the connection's stored public platform:agent-device/src/cli/commands/connection-runtime.ts
Lines 955 to 961 in 76dbee0
so
ios !== appleand the request is refused. Android passes because its internal and public names are bothandroid.Repro
agent-device 0.21.12 (same code on
mainat 76dbee0): open a remote connection withplatform: iosand a proxy lease, then runinstall <app>(oropen) against the leased device. It fails right after the device lookup, before a lease is taken.Possible fix
Store the public name in the flags, e.g.
flags.platform = publicPlatformString(device)(already used bybuildProxyDeviceKeyin the same file), or normalize both sides before the comparison.Context
Found through Stim (appandflow/stim#1096). Stim works around it by keeping iOS on the default 60 s lease (appandflow/stim#1127), which means large iOS apps can still hit #2946 (lease not renewed during upload); fixing this would let iOS use the longer proxy lease.