You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
beta.opencode.ai QR code scanner rejects opencode pair QR code #55027
Thanks for the report and the screenshot. You weren't doing anything wrong: I could reproduce this with v2.0.27.
What I found:
opencode pair --remote (and plain opencode pair) puts the pairing code and the server addresses in the QR code as {"code": …, "urls": […]}. This format came with the one-time pairing links.
The scanner currently live on beta.opencode.ai comes from an older web build, from before one-time links. When I ran that site's own parser on the QR from 2.0.27, it rejected it, which is why you see "This is not an OpenCode pairing code".
The web app code on the latest dev (d782675) reads the same QR correctly. So the problem is that beta.opencode.ai hasn't been redeployed with the current app, not the CLI. I've passed this on to the maintainers.
Until the site is updated, a workaround: open the printed https://…opentunnel.xyz/auth/connect/<code> link directly on your phone, for example by scanning it with the camera's link scanner or sending it to yourself. That link signs you in to your server's own web UI. It works once and expires after 5 minutes.
The script below reproduces the mismatch against the live site.
Related: #54627 (iOS app can't connect through pair --remote, a different "server unreachable" error) and #54871 (the opencode pair QR code encodes the 127.0.0.1 link when the server listens on 0.0.0.0).
Reproduction script (repro.sh)
#!/usr/bin/env bash# Repro for #55027: beta.opencode.ai's QR scanner rejects the QR payload printed by `opencode pair` (v2.0.27).set -euo pipefail
W=/tmp/opencode/beta55027; mkdir -p "$W";cd"$W"# 1. What the CLI puts in the QR code (v2.0.27, packages/cli/src/commands/handlers/pair.ts):# JSON.stringify({ code: pairing.code, urls: remote }) e.g. for `opencode pair --remote`:
PAYLOAD='{"code":"f4GJvk8uW-WUlHaWFDSSLA","urls":["https://3273fd28333c4db5.de3b3udkwehl.opentunnel.xyz"]}'# 2. Download the scanner's parser that beta.opencode.ai actually serves, with its dependencies.
curl -sL https://beta.opencode.ai/ -o index.html
forfin$(grep -o '/_assets/[^"]*\.js' index.html | sort -u);do curl -sfL "https://beta.opencode.ai$f" -o "$(basename "$f")";doneforiin 1 2 3;doforfin$(grep -oh -- '[A-Za-z0-9_.-]*-[A-Za-z0-9_-]\{8\}\.js' ./*.js | sort -u);do
[ -f"$f" ] || curl -sfL "https://beta.opencode.ai/_assets/$f" -o "$f"||truedonedone
SCANNER=$(grep -l -- 'server.connect.scan.invalid' ./scanner-*.js | head -1)echo"Deployed build: $(grep -o 'web@[0-9a-f]*'"$SCANNER"| head -1)"# The scanner calls the parser it imports from the browser-*.js chunk; a falsy result shows "This is not an OpenCode pairing code".
BROWSER=$(grep -o 'from"\./browser-[^"]*"'"$SCANNER"| grep -o 'browser-[^"]*')
NAME=$(grep -o 'import{n as p}from"\./browser'"$SCANNER">/dev/null &&echo n)
cat > t.mjs <<JSglobalThis.window = globalThis;const m = await import("./$BROWSER");console.log("deployed parser, v2.0.27 {code,urls} payload ->", m.$NAME(process.argv[2]));console.log("deployed parser, old {urls,username,password} payload ->", m.$NAME(JSON.stringify({ urls: ["https://x.example"], username: "opencode", password: "p" })));JS
bun t.mjs "$PAYLOAD"# 3. The same payload against the app code on dev (needs a checkout of dev with `bun install` done).if [ -d /workspace/repo/packages/app ];then
cat > /workspace/repo/packages/app/repro-55027.ts <<'TS'import { pairingLink } from "./src/servers/connect/pairing"console.log("dev pairingLink ->", pairingLink(process.argv[2]))TS
(cd /workspace/repo/packages/app && bun repro-55027.ts "$PAYLOAD"; rm -f repro-55027.ts)
fi
Activity
opencode-agent commentedon Oct 13, 2026
Thanks for the report and the screenshot. You weren't doing anything wrong: I could reproduce this with v2.0.27.
What I found:
opencode pair --remote(and plainopencode pair) puts the pairing code and the server addresses in the QR code as{"code": …, "urls": […]}. This format came with the one-time pairing links.dev(d782675) reads the same QR correctly. So the problem is that beta.opencode.ai hasn't been redeployed with the current app, not the CLI. I've passed this on to the maintainers.Until the site is updated, a workaround: open the printed
https://…opentunnel.xyz/auth/connect/<code>link directly on your phone, for example by scanning it with the camera's link scanner or sending it to yourself. That link signs you in to your server's own web UI. It works once and expires after 5 minutes.The script below reproduces the mismatch against the live site.
Related: #54627 (iOS app can't connect through
pair --remote, a different "server unreachable" error) and #54871 (theopencode pairQR code encodes the127.0.0.1link when the server listens on0.0.0.0).Reproduction script (repro.sh)
Run it:
bash repro.sh