{"record":{"id":"d99afac901c82a9e","repo":"stablyai/orca","slug":"adb-did-not-return-a-local-scrcpy-port","errorCode":null,"errorMessage":"adb did not return a local scrcpy port","messagePattern":"adb did not return a local scrcpy port","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main/emulator/android/scrcpy-stream-session.ts","lineNumber":113,"sourceCode":"      throw error\n    }\n    return session\n  }\n\n  private async deploy(): Promise<void> {\n    const { runner, sdk, serial, localJarPath } = this.options\n    ensureAdbOk(\n      await runner(sdk.adb, pushScrcpyServerArgs(serial, localJarPath, SCRCPY_DEVICE_JAR_PATH)),\n      'scrcpy server push'\n    )\n    const forward = ensureAdbOk(\n      await runner(sdk.adb, scrcpyForwardArgs(serial, this.port, this.scid)),\n      'scrcpy port forward'\n    )\n    if (this.port === DYNAMIC_FORWARD_PORT) {\n      const allocated = Number.parseInt(forward.stdout.trim(), 10)\n      if (!Number.isFinite(allocated) || allocated <= 0) {\n        throw new Error('adb did not return a local scrcpy port')\n      }\n      this.port = allocated\n      emulatorProbe('scrcpy.forward.port', { serial, port: this.port })\n    }\n  }\n\n  private spawnServer(): void {\n    const { sdk, serial, maxSize } = this.options\n    // The server is long-running, so spawn it directly rather than via the\n    // request/response command runner.\n    this.server = spawn(sdk.adb, startScrcpyServerArgs(serial, { scid: this.scid, maxSize }), {\n      stdio: ['ignore', 'pipe', 'pipe']\n    })\n    let serverLog = ''\n    const capture = (chunk: Buffer): void => {\n      serverLog += chunk.toString()\n    }\n    this.server.stdout?.on('data', capture)","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/emulator/android/scrcpy-stream-session.ts#L95-L131","documentation":"Thrown by ScrcpyStreamSession.deploy when a dynamic port forward was requested (this.port === 0) but the adb forward output could not be parsed as a finite positive integer. adb is expected to print the allocated local port number to stdout when forwarding to 'tcp:0'; anything else means the forward command misbehaved or the output format changed.","triggerScenarios":"ScrcpyStreamSession.start called with no localPort (defaulting to DYNAMIC_FORWARD_PORT=0); the scrcpyForwardArgs adb invocation succeeded (ensureAdbOk passed) but forward.stdout.trim() does not parseInt to a positive number — e.g. empty output, an error string, or a newer adb printing differently.","commonSituations":"An older or newer adb version with different forward-output formatting; the forward succeeded structurally but printed a status line instead of a port; a locale/format quirk; adb server in an odd state returning empty stdout while exiting 0.","solutions":["Update platform-tools to a version whose `adb forward tcp:0 ...` prints the allocated port to stdout.","Pass an explicit localPort in ScrcpyStreamOptions to skip the dynamic allocation path entirely.","Run `adb forward --list` and `adb forward tcp:0 tcp:<port>` manually to see what your adb prints and reconcile.","Restart the adb server if its state is corrupt."],"exampleFix":"// before: dynamic port, adb prints nothing usable\nawait ScrcpyStreamSession.start({ runner, sdk, serial, localJarPath }, cb)\n// after: pin a local port\nawait ScrcpyStreamSession.start({ runner, sdk, serial, localJarPath, localPort: 27183 }, cb)","handlingStrategy":"fallback","validationCode":"// Pin a local port to skip dynamic allocation entirely.\nconst opts: ScrcpyStreamOptions = { runner, sdk, serial, localJarPath, localPort: 27183 }","typeGuard":"function isDynamicPortError(e: unknown): e is Error {\n  return e instanceof Error && /did not return a local scrcpy port/i.test(e.message)\n}","tryCatchPattern":"try {\n  return await ScrcpyStreamSession.start(opts, cb)\n} catch (e) {\n  if (isDynamicPortError(e)) {\n    // fall back to a fixed local port\n    return await ScrcpyStreamSession.start({ ...opts, localPort: 27183 }, cb)\n  }\n  throw e\n}","preventionTips":["Pass an explicit localPort to avoid relying on adb's dynamic-port output format.","Keep platform-tools current so adb forward tcp:0 prints the allocated port.","Restart the adb server if forward output is unexpectedly empty."],"tags":["scrcpy","adb","port-forward","version-compat","android"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}