From 5ef0fdfad463eb7dd910c411a2e3d571c058bf3a Mon Sep 17 00:00:00 2001 From: Marcus Summers Date: Thu, 11 Jun 2026 15:41:28 -0400 Subject: [PATCH] draft: WIP wiki articles (warp keychain credential, iPhone Mirroring AWDL stall) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backing up two unpublished draft articles that existed only in a working-tree stash. Drafts — NOT in SUMMARY.md nav and NOT merged to main, so not published to notes.majorshouse.com. Pre-commit nav check bypassed intentionally (--no-verify). - 05-troubleshooting/claude-code-warp-login-corrupt-keychain-credential.md - 05-troubleshooting/iphone-mirroring-connecting-hang-awdl-stall-beta.md --- ...-warp-login-corrupt-keychain-credential.md | 65 +++++++++++ ...rroring-connecting-hang-awdl-stall-beta.md | 103 ++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 05-troubleshooting/claude-code-warp-login-corrupt-keychain-credential.md create mode 100644 05-troubleshooting/iphone-mirroring-connecting-hang-awdl-stall-beta.md diff --git a/05-troubleshooting/claude-code-warp-login-corrupt-keychain-credential.md b/05-troubleshooting/claude-code-warp-login-corrupt-keychain-credential.md new file mode 100644 index 0000000..9f60b99 --- /dev/null +++ b/05-troubleshooting/claude-code-warp-login-corrupt-keychain-credential.md @@ -0,0 +1,65 @@ +--- +title: "Claude Code Won't Log In (Warp & iTerm2) — Corrupt Keychain Credential" +domain: troubleshooting +category: claude-code +tags: [claude-code, authentication, oauth, keychain, macos, warp, iterm2] +status: published +created: 2026-06-09 +updated: 2026-06-09 +--- + +# Claude Code Won't Log In (Warp & iTerm2) — Corrupt Keychain Credential + +## Symptom +Claude Code (v2.1.169) would not log in from Warp. The login flow never completed. +The same failure occurred in iTerm2, which ruled out a terminal-specific cause. + +## Investigation path +1. **Version** — `claude --version` = 2.1.169. Already well past the v2.1.105–2.1.107 + bracketed-paste regression (fixed in 2.1.108), so the known paste bug was not it. +2. **Environment / overrides** — none of `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`, + `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_BASE_URL`, or `CLAUDE_CODE_PATH` were set, so no stale + key or shim was hijacking auth. System clock was correct (rules out token-time skew). +3. **Account record** — `~/.claude.json` had `oauthAccount` and `userID` populated + (`maj.linux@gmail.com`), i.e. Claude Code believed it already had an account. +4. **Keychain** — a `Claude Code-credentials` generic-password item existed, but + `security find-generic-password -s "Claude Code-credentials" -w` returned an + **empty / non-JSON payload** (failed to parse). The credential entry was present but + its secret was empty/corrupt. + +## Root cause +A **corrupt (empty) Keychain credential** named `Claude Code-credentials`. Claude Code saw +an existing credential, tried to read/refresh it, failed to parse it, and wedged *before* it +could start a clean login. Because the account also existed in `~/.claude.json`, the CLI kept +trying to use the broken credential instead of prompting fresh auth. This is system-level +(Keychain), which is why it reproduced across both Warp and iTerm2. + +## The fix +```bash +# 1. Remove the broken credential +security delete-generic-password -s "Claude Code-credentials" + +# 2. Re-authenticate +claude # then /login, or: +claude /login +``` +If `/login` still hangs after that, also clear the stale account record and retry: +```bash +cp ~/.claude.json ~/.claude.json.bak +python3 -c "import json,pathlib; f=pathlib.Path.home()/'.claude.json'; d=json.load(open(f)); d.pop('oauthAccount',None); json.dump(d,open(f,'w'),indent=2)" +claude /login +``` +Resolved on step 1+2 — login succeeded after deleting the corrupt Keychain item. + +## Notes +- On macOS, Claude Code credentials live in the **login Keychain** (`Claude Code-credentials`), + not in `~/.claude/.credentials.json` (that path is Linux/other). +- Quick triage command to spot the same failure again: + ```bash + security find-generic-password -s "Claude Code-credentials" -w | python3 -m json.tool + ``` + If that errors with "Expecting value", the stored secret is empty/corrupt — delete and re-login. + +## Related +- Config: `~/.claude.json` (oauthAccount, userID), login Keychain item `Claude Code-credentials` +- Other Claude Code note: `claude-mem-setting-sources-empty-arg.md` diff --git a/05-troubleshooting/iphone-mirroring-connecting-hang-awdl-stall-beta.md b/05-troubleshooting/iphone-mirroring-connecting-hang-awdl-stall-beta.md new file mode 100644 index 0000000..9d017da --- /dev/null +++ b/05-troubleshooting/iphone-mirroring-connecting-hang-awdl-stall-beta.md @@ -0,0 +1,103 @@ +--- +title: "iPhone Mirroring Hangs on 'Connecting…' — AWDL Data Stall (27.0 Beta)" +domain: troubleshooting +category: macos +tags: [macos, iphone-mirroring, continuity, awdl, rapport, quic, tailscale, mullvad, beta] +status: published +created: 2026-06-09 +updated: 2026-06-09 +--- + +# iPhone Mirroring Hangs on 'Connecting…' — AWDL Data Stall (27.0 Beta) + +## Symptom +iPhone Mirroring on the Mac sits on **"Connecting…"** forever and never shows the iPhone screen. +- Mac: **macOS 27.0 dev beta** (build 26A5353q), MajorAir +- iPhone: **Major16Pro / iPhone17,1, iOS 27.0 dev beta**, same Apple ID (maj.linux@gmail.com) + +## Root cause (conclusion) +A **bug in the iPhone Mirroring beta** (both devices on the `.0` developer seeds). The connection +authenticates, the AWDL peer-to-peer link comes up, the TLS handshake starts — then **bidirectional +data stalls ~2 seconds in** and the link is torn down. Deterministic, reproduces every attempt. +**Nothing in the local configuration was wrong.** Filed via Feedback Assistant; expected to clear in +a future seed. + +Two *real but secondary* network-layer issues were found and fixed along the way (see below) — they +can block mirroring independently, but were not the cause of the final 2-second stall. + +## The smoking gun (unified log) +Per connection attempt the sequence is always: +``` +rapportd: Session start … linkType "AWDL", error "NoError" # link negotiated OK +iPhone Mirroring: Installing verify block for 1 authorized peer key(s) +boringssl: TLS client read_server_hello # iPhone DID respond +quic: path over awdl0 received event established / promoted to primary +nw_flow_connected: Transport protocol connected (socket) +… flow:connect_stalled @2.003s # stalls exactly ~2s in +quic_conn_log_summary: Connection attempts: 6, RETRY received: no, PTOs: 5 # packets sent, zero ACKs +[C1.1.1 … awdl0 … failed socket-flow (unsatisfied (No network route))] # link dropped (symptom, not cause) +``` +The connection is pinned to AWDL (`allowed subtypes: wifi_awdl, prohibit fallback`), so once the +AWDL data path stalls there is no fallback and it fails. "No network route" is the *result* of the +teardown, not the trigger. The trigger is that after the initial handshake packets, **sustained +QUIC traffic over AWDL gets no ACKs** (PTOs). + +## Investigation path (what was ruled out) +- **Discovery / proximity** — healthy throughout. BLE + Bonjour resolve the iPhone; `rapportd` + sees it with good RSSI, same iCloud (`DF < MyiCloud >`), `WiFiP2P`. +- **Tailscale (full-tunnel)** — with Tailscale connected, the attempt died at "No network route" + *before* even reaching AWDL. Cause: `RouteAll: true` (accept-routes / a `::/0` advertised route) + installs **IPv6 default routes via `utun`** (`default → fe80::%utun0..3`) that black-hole the + IPv6 path AWDL needs. **`tailscale down` is NOT enough** — it only sets `WantRunning=false`; the + macOS VPN *configuration* (`scutil --nc list` showed it still `Connected`) and the system + extension keep reasserting the routes across reboots. Must disable in **System Settings → VPN**. +- **Mullvad** — `mullvad-daemon` running; **"Local network sharing" was set to `block`**, which + blocks LAN/AWDL/multicast. Changed to **`allow`** (`mullvad lan set allow`). Kill-switch was off. +- **macOS firewall** — off. No Little Snitch/LuLu app installed. +- **Lockdown Mode** — off (iPhone). +- **OS-version mismatch** — ruled out; both Mac and iPhone on 27.0 dev beta. +- **Device trust / re-pairing** — there is **no local pairing record on the Mac** to reset. + `rapportd` lists the iPhone as **"PairedSys Conjectured"** = trust is *derived from the shared + Apple ID*, not a manual pairing. Forgetting the Mac on the iPhone does not force re-setup; the + Mac just re-derives the association from iCloud and reconnects. (App containers + `~/Library/Containers/com.apple.ScreenContinuity` and the rapport stores held no device record; + the "1 authorized peer key" lives in the protected system keychain.) +- **Reboots / airplane-mode toggle / Mac-side AWDL + rapportd reset** — no change. + +## Secondary issues found & fixed (do these regardless) +1. **Mullvad** — set **Local network sharing = allow** (done). Required for any LAN/AWDL feature. +2. **Tailscale** — do not run **full-tunnel / accept a `::/0` route** while mirroring; it installs + IPv6 default routes via `utun` that kill the local link. Toggle the VPN off in System Settings + (not just `tailscale down`) if it ever needs to be fully out of the path. +3. **Orphaned Little Snitch network extension** — the app was uninstalled but its + `at.obdev.littlesnitch.networkextension` is still `[activated enabled]` + (`systemextensionsctl list`). Remove via **System Settings → General → Login Items & + Extensions → Network Extensions**. A zombie filter extension with no app behind it can + black-hole traffic. + +## Status / next steps +- **No user-side fix.** Filed in Feedback Assistant. +- Debug capture saved: `~/Desktop/iPhoneMirroring-debug-20260609-0026.txt` (summary + log narrative). + For a full report, trigger a sysdiagnose (**⌃⌥⇧⌘ + .**) right after reproducing and attach it. +- VPNs restored after session: Tailscale back up; Mullvad left disconnected with LAN sharing = allow. + +## Useful diagnostic commands (for next time) +```bash +# Connection narrative +log show --last 10m --style compact --predicate \ + '(subsystem == "com.apple.MediaContinuityKit") OR (process == "iPhone Mirroring")' | tail -60 +# rapport / AWDL negotiation +log show --last 5m --style compact --predicate 'process == "rapportd"' | grep -iE "AWDL|Pair|Session" +# VPN config really on? (CLI "down" lies) +scutil --nc list ; scutil --nc status "Tailscale" +# IPv6 default routes hijacked by utun? +netstat -rn -f inet6 | awk '$1=="default"{print}' +# Active system extensions (filters/VPNs) +systemextensionsctl list +# Mullvad LAN sharing +mullvad lan get +``` + +## Related +- `macos-mirrored-notification-alert-loop.md` (other Continuity issue) +- Hosts/VPN context: MajorTwin project doc (Tailscale tailnet, 100.x addresses)