# Troubleshooting

> Terminal support issues (tmux, SSH, truecolor, OSC 52 clipboard), color warnings, auth recovery, MCP startup failures, and diagnostics probes backed by the pager diagnostics module.

- Repository: xai-org/grok-build
- GitHub: https://github.com/xai-org/grok-build
- Human docs: https://grok-wiki.com/public/docs/xai-org-grok-build-90205de50458
- Complete Markdown: https://grok-wiki.com/public/docs/xai-org-grok-build-90205de50458/llms-full.txt

## Source Files

- `crates/codegen/xai-grok-pager/docs/user-guide/21-terminal-support.md`
- `crates/codegen/xai-grok-pager/src/diagnostics.rs`
- `crates/codegen/xai-grok-pager/docs/user-guide/02-authentication.md`
- `crates/codegen/xai-grok-shell/src/auth/recovery.rs`
- `crates/codegen/xai-grok-shell/src/mcp_doctor.rs`
- `crates/codegen/xai-tty-utils/src`
- `crates/codegen/xai-grok-shell/README.md`

---

---
title: "Troubleshooting"
description: "Terminal support issues (tmux, SSH, truecolor, OSC 52 clipboard), color warnings, auth recovery, MCP startup failures, and diagnostics probes backed by the pager diagnostics module."
---

Grok Build surfaces failures through a route-aware pager diagnostics engine (`/terminal-setup`), automatic 401 auth recovery against `~/.grok/auth.json`, and `grok mcp doctor` probes that start configured MCP servers and report per-check health.

## First probes

| Surface | When to use | What it reports |
|---------|-------------|-----------------|
| `/terminal-setup` (aliases `/terminal-check`, `/terminal-info`) | Colors, clipboard, keyboard, tmux/SSH oddities inside the TUI | Terminal brand, multiplexer, SSH flag, color level, available themes, clipboard routes, structured issues + fixes |
| Welcome-screen startup banners | Over SSH or for high-priority local input/clipboard issues | Short summary; full detail is in `/terminal-setup` |
| `grok mcp doctor` | MCP servers fail to start or expose tools | Config sources, per-server checks, exit 1 if any fail |
| `grok --debug` / `GROK_LOG_FILE` | Auth, network, spawn failures | File logs (TUI captures stderr; bare `RUST_LOG` alone is not enough) |
| `grok login` / `grok logout` | Session rejected or wrong account | Replaces or clears `~/.grok/auth.json` |

<Tip>
Run `/terminal-setup` first for any TUI display, color, or clipboard issue. Expect `color truecolor` and `themes all` when 24-bit RGB is available.
</Tip>

---

## Terminal diagnostics

The pager diagnostics module classifies environment problems into structured `TerminalWarning` records (category, message, optional fix, config path, note). `/terminal-setup` runs the same engine used for startup warnings and prints:

1. **Environment** — terminal brand, optional XTVERSION self-report, multiplexer/Byobu, SSH, color level, themes, keyboard/newline notes  
2. **Clipboard routes** — native tool, tmux buffer, OSC 52, Wayland data-control  
3. **Issues** — each warning with fix/note when available  

### Detected terminals

Brand detection uses environment variables and (over SSH) XTVERSION. Known brands include Apple Terminal, Ghostty, iTerm2, Warp, WezTerm, Kitty, Alacritty, Rio, foot, VS Code / Cursor / Windsurf / Zed, JetBrains IDEs, Grok Desktop, VTE-based terminals, and Windows Terminal.

Detection limits:

- Inside tmux, outer terminal identity often does not reach the pager  
- Over SSH, many terminal variables are not forwarded  
- tmux’s global environment reflects the first client that attached to the server, not the current client  

### Warning categories

| Category | Typical cause | Primary fix |
|----------|---------------|-------------|
| `Clipboard` | tmux `set-clipboard` not `on`/`external` | `set -g set-clipboard on` in tmux config |
| `DcsPassthrough` | tmux `allow-passthrough` off (tmux 3.3+) | `set -g allow-passthrough on` |
| `ControlMode` | `tmux -CC` / control mode | Expect inline or unreliable fullscreen; force with `[terminal] alt_screen = "always"` if needed |
| `ByobuScreen` | Byobu on GNU screen | Prefer Byobu on tmux |
| `UnsupportedTerminal` | Apple Terminal over SSH (no OSC 52) | Use OSC 52–capable terminal or `grok wrap` |
| `TmuxExtendedKeysOff` | `extended-keys` off | `set -g extended-keys on` then reload tmux |
| `WezTermKittyKeyboardOff` | Kitty keyboard protocol off | `config.enable_kitty_keyboard = true` in `wezterm.lua` (local); `\` then Enter over SSH |
| `WaylandNoDataControl` | Compositor lacks data-control | Stay focused mid-copy; install `wl-clipboard` when suggested |
| `LimitedColorSupport` | Below truecolor / `NO_COLOR` | `COLORTERM=truecolor`, tmux RGB features, or switch terminal |
| `FocusTrackingUnavailable` | Unfocused notifications on unsupported brand | `[ui.notifications] condition = "always"` |
| `SandboxProfileConflict` | Project vs user sandbox profile clash | Prefer user `~/.grok/sandbox.toml` (banner notes the resolution) |

Query failure is silent: a missing tmux option value does **not** warn. Only an explicit non-good value (for example `set-clipboard off`) produces a clipboard/DCS warning.

Welcome-screen summarization is SSH-gated for most tmux clipboard noise. Local high-priority banners include WezTerm Shift+Enter, Wayland focus-dependent copies, and sandbox profile conflicts.

---

## Truecolor and washed-out themes

Truecolor-only themes stay hidden when color level is below truecolor. `/terminal-setup` shows the level and which themes remain.

<Steps>
  <Step title="Set COLORTERM">
    ```bash
    # ~/.zshrc or ~/.bashrc
    export COLORTERM=truecolor
    ```
  </Step>
  <Step title="Configure tmux for 24-bit RGB">
    ```tmux
    # ~/.tmux.conf
    set -g default-terminal "tmux-256color"
    set -as terminal-features ",*:RGB"
    ```
    Then `tmux source-file ~/.tmux.conf` (or detach/reattach) and restart Grok.
  </Step>
  <Step title="Verify">
    Run `/terminal-setup`. Expect `color truecolor` and `themes all`. Apple Terminal is inherently 256-color — truecolor themes stay unavailable; switch to a truecolor terminal (for example Ghostty) if needed.
  </Step>
</Steps>

If `NO_COLOR` is set, themed colors are disabled; unset it and restart Grok.

---

## Clipboard (native, tmux, OSC 52)

Grok may write through up to three routes (shown under **Clipboard routes** in `/terminal-setup`):

| Route | Behavior |
|-------|----------|
| **native** | OS clipboard first (tool name printed next to the row) |
| **tmux buffer** | Also `tmux load-buffer` when inside tmux |
| **OSC 52** | Escape sequence for the outer terminal. Always emitted inside tmux; outside tmux, on Linux, over SSH, or in a container without a display |

Recommended tmux clipboard + passthrough:

```tmux
set -g set-clipboard on
set -g allow-passthrough on
```

### Platform notes

**Linux Wayland** — With compositor data-control (GNOME 48+, KDE, Sway, Hyprland; `/terminal-setup` `data-control` row = `yes`), copies work even if the terminal loses focus. Without it, keep focus until the copy toast confirms and install `wl-clipboard` (`wl-copy`) when suggested. To force CLI tools only: `GROK_CLIPBOARD_NO_DATA_CONTROL=1`.

**Linux X11** — PRIMARY and CLIPBOARD are separate. Middle-click (unmodified) can read PRIMARY when `DISPLAY` is set; `Ctrl+V` reads CLIPBOARD only. `Shift+Insert` remains terminal-native selected-text paste.

**SSH selected text** — A remote Grok process usually cannot read the local terminal’s PRIMARY/CLIPBOARD. Use terminal-native `Shift+Insert`, or hold `Shift` while middle-clicking when the terminal uses that gesture to bypass mouse reporting.

**iTerm2** — Enable **Settings → General → Selection → “Applications in terminal may access clipboard”** (off by default). Without it, OSC 52 writes are ignored.

**Apple Terminal + SSH** — Terminal.app ignores OSC 52, so remote copies never reach the local clipboard.

### `grok wrap` (experimental)

```bash
grok wrap ssh user@host
grok wrap docker exec -it <container> bash
grok wrap kubectl exec -it <pod> -- bash
```

`grok wrap` runs the command in a local PTY, intercepts OSC 52 (including tmux-wrapped DCS forms), and writes payloads to the local clipboard. Useful when the outer terminal or remote environment cannot deliver clipboard itself.

<Warning>
`grok wrap` is experimental and may misbehave in some setups. On PTY setup failure it falls back to an unwrapped exec.
</Warning>

---

## Keyboard and mouse

### WezTerm: Shift+Enter / Ctrl+Enter

WezTerm defaults `enable_kitty_keyboard = false`. Without the Kitty keyboard protocol, Shift+Enter is byte-identical to Enter (submits instead of newline), and stock Alt+Enter toggles fullscreen.

```lua
-- ~/.config/wezterm/wezterm.lua (after config = wezterm.config_builder())
config.enable_kitty_keyboard = true
```

Reload WezTerm and restart `grok`. Until fixed, type `\` then Enter for a newline. Over SSH, the pager does not yet negotiate the protocol for WezTerm; the same `\`+Enter workaround applies.

### VS Code / Cursor / Windsurf / Zed: Shift+Enter

xterm.js mis-encodes shifted keys, so Grok does not negotiate Kitty keyboard protocol. Use **Alt+Enter** for newline. `/terminal-setup` shows `newline Alt+Enter (...)` when this applies. Same over SSH when `TERM_PROGRAM` is not forwarded (brand falls back to Unknown).

### Apple Terminal interject

Grok binds **Ctrl+O** to interject (Ctrl+Enter is unreliable).

### tmux extended keys

If `extended-keys` is off, modifier chords may not reach the pager:

```tmux
set -g extended-keys on
```

Reload with `tmux source-file <config>` or detach/reattach.

### Mouse reporting

If Grok scrolling stops and the native scrollbar takes over:

- **Apple Terminal:** View → Allow Mouse Reporting (`Cmd+R`)  
- **iTerm2:** Profiles → Terminal → Enable mouse reporting  

### Zellij key interception

Zellij intercepts many Ctrl/Alt chords. On Zellij 0.41+, use the **Unlock-First (non-colliding)** preset so keys pass through while locked; unlock with `Ctrl+g` for Zellij pane management.

### Fullscreen / alternate screen

Zellij and tmux control mode intentionally run inline (no alt screen) unless forced:

```toml
# ~/.grok/pager.toml
[terminal]
alt_screen = "always"
```

CLI: `--no-alt-screen` disables alt-screen entirely for debugging.

### Byobu

Byobu on GNU screen is best-effort only. Prefer Byobu backed by tmux.

---

## Authentication recovery

On HTTP 401, `UnauthorizedRecovery` walks:

1. **ReloadFromDisk** — re-read `~/.grok/auth.json` under a file lock; adopt the token only if it differs from the rejected one (another process may have refreshed)  
2. **RefreshFromAuthority** — OIDC refresh or external auth binary, unless the live token is inside the ±120s fresh-mint guard (avoids re-minting on stale/lagged 401s)  
3. **DevboxRecovery** — on devbox environments, purge and mint fresh OIDC when automatic OIDC is allowed  
4. **Done** — recovery exhausted  

| Outcome / error | User action |
|-----------------|-------------|
| Silent recovery success | None; request retries with new token |
| Transient refresh failure | Retries stay allowed; do not force re-login on a blip |
| `Token expired` / `RecoveryExhausted` / permanent refresh reject | `grok login` |
| API key / legacy session (no refresh authority) | Rotate key or `grok login`; 401 stands after disk reload |
| Pinned team mismatch | `grok login` with the required team |
| API-key auth disabled by admin | `grok login` (OIDC/session path) |

### Manual recovery

```bash
# Re-run sign-in (replaces cached session)
grok login
# Headless / remote: device-code flow
grok login --device-auth

# Clear session so XAI_API_KEY can take over
grok logout
# or delete ~/.grok/auth.json

export XAI_API_KEY="xai-..."
```

Stored session tokens take precedence over `XAI_API_KEY` while present. Credentials without a server-provided expiry fall back to a 30-day lifetime in the authentication docs; tokens refresh in the background when a refresh authority exists.

### Debug auth

```bash
# Custom path; filter module-level if needed
GROK_LOG_FILE=/tmp/grok-auth.log RUST_LOG="info,xai_grok_shell::auth=debug" grok -p "hello"
grep "auth:" /tmp/grok-auth.log

# Per-session debug firehose
grok --debug
tail -f ~/.grok/debug/latest.txt
```

External auth provider failures surface as spawn failures, empty/unparseable stdout, non-zero exit, or timeouts (initial ~60s, mid-session refresh ~5s). Ensure the binary prints **only** the token on stdout and status/URLs on stderr.

---

## MCP startup failures

`grok mcp doctor` discovers servers from user/project `config.toml`, plugins, Claude import paths (when not skipped), `.mcp.json`, and managed `grok.com` servers when xAI OIDC auth is eligible. It then probes (up to 8 concurrent):

| Check | Failure meaning | Hint direction |
|-------|-----------------|----------------|
| command found (stdio) | Binary not on `PATH` | Fix command / install tool |
| server started | Spawn or timeout | Permissions, args, `startup_timeout_sec` |
| handshake OK | Protocol init failed | Server logs / transport URL |
| N tools discovered | Empty or failed `tools/list` | Server config / logs |
| disabled in config | Listed in `disabled_mcp_servers` or `enabled = false` | Enable server |
| folder untrusted | Project-scoped server in untrusted clone | Re-run with trust for that folder |
| blocked by organization policy | Managed allowlist deny | Org policy / allowlist |

```bash
grok mcp doctor               # all servers
grok mcp doctor github        # one name
grok mcp doctor --json        # machine-readable DoctorReport
```

Exit status is non-zero when any probed server fails, or when a name filter matches nothing.

Common config fix for slow spawns:

```toml
[mcp_servers.filesystem]
startup_timeout_sec = 30
```

Test the stdio command outside Grok first (`npx …`, absolute path, env vars). Prefer native HTTP/SSE `url` entries over wrapping remote MCP in extra stdio proxies when the server exposes HTTP.

Managed discovery skips with reasons such as `not logged in`, `auth expired — run grok login`, non-xAI auth mode, or fetch errors. Claude-imported sources may show as skipped when `claude_compat imported = true`.

---

## Debug logging and inspect

| Mechanism | Behavior |
|-----------|----------|
| `grok --debug` | Per-session log under `~/.grok/debug/<sessionId>.txt`; fixed first-party `debug` filter (not narrowed by `RUST_LOG`) |
| `GROK_LOG_FILE=/path` | Custom log file; defaults to `debug`, honors `RUST_LOG` filters |
| `~/.grok/debug/latest.txt` | Symlink to most recent session log (Unix) |
| `grok inspect` / `grok inspect --json` | Resolved project instructions, skills, plugins, MCP, hooks, permissions for the current directory |

TTY-owned child processes are detached via `xai_tty_utils` (`setsid` / `setpgid` on Unix, `CREATE_NO_WINDOW` on Windows) so tools and diagnostic subprocesses do not steal the TUI’s controlling terminal. Unexpected mouse garbage or credential prompts in the TUI usually mean a child still opened `/dev/tty` — report via `/feedback` with environment details from `/terminal-setup`.

---

## Quick failure matrix

| Symptom | Likely cause | Action |
|---------|--------------|--------|
| Washed-out / missing truecolor themes | No RGB / missing `COLORTERM` | Export `COLORTERM=truecolor`; tmux RGB features; `/terminal-setup` |
| Copy over SSH fails (Apple Terminal) | No OSC 52 | `grok wrap ssh …` or switch terminal |
| Copy fails in tmux | `set-clipboard` / passthrough off | Enable both; reload tmux |
| Shift+Enter submits (WezTerm) | Kitty keyboard off | Enable in `wezterm.lua` or `\`+Enter |
| Shift+Enter submits (VS Code family) | xterm.js limitation | Alt+Enter |
| Keys stolen (Zellij) | Zellij bindings | Unlock-First preset |
| Inline instead of fullscreen | Control mode / Zellij | Expected, or `alt_screen = "always"` |
| Re-auth banner / 401 loop | Recovery exhausted | `grok login`; check logs for `auth:` |
| MCP tools missing | Spawn/handshake/disabled/untrusted | `grok mcp doctor --json` |
| Mouse scroll broken | Mouse reporting off | Terminal setting (Apple Terminal / iTerm2) |

Still stuck after probes: run `/feedback` with `/terminal-setup` output (and `grok mcp doctor --json` when MCP is involved).

## Related pages

<CardGroup>
  <Card title="Authentication" href="/authentication">
    Login flows, device code, API keys, and credential storage in `~/.grok/auth.json`.
  </Card>
  <Card title="MCP servers" href="/mcp-servers">
    Register and manage stdio/HTTP MCP servers, timeouts, and enable/disable flags.
  </Card>
  <Card title="Theming" href="/theming">
    Color-support detection, truecolor-only themes, and `/theme`.
  </Card>
  <Card title="Configure Grok" href="/configure-grok">
    `config.toml` / `pager.toml` precedence and `grok inspect`.
  </Card>
  <Card title="Keyboard shortcuts" href="/keyboard-shortcuts">
    Interject, newline chords, and multipress Escape behavior.
  </Card>
  <Card title="CLI reference" href="/cli-reference">
    Top-level commands including `wrap`, `mcp`, `login`, `inspect`, and `update`.
  </Card>
</CardGroup>
