Troubleshooting

Common issues and how to resolve them.

The usual suspects, and how to get unstuck.

h2 socket hangup (server accepted request; not replayed automatically)

The connection died mid-answer, after the provider had already started streaming. agentty deliberately does not retry at that point: the turn is semantically committed, and replaying it could duplicate the assistant message or re-run tool calls.

This is almost always the network, not agentty and not the model. Corporate proxies, VPNs and CDN edges routinely kill idle HTTP/2 connections at 30-60 seconds; agentty's connection pool holds them for 90, so it can hand you a socket the network already closed.

Find out which:

grep http.stream_hangup ~/.agentty/logs/agentty.log
W net  http.stream_hangup: host=api.anthropic.com:443 reused=1 idle_ms=61402 status=200 …
  • idle_ms clusters near a round number (30000, 60000) and reused=1 — a network idle timeout. Set AGENTTY_POOL_IDLE_TTL below it:

``bash AGENTTY_POOL_IDLE_TTL=45 agentty # evict before the network does AGENTTY_POOL_IDLE_TTL=0 agentty # no pooling at all (safest, slower) ``

  • idle_ms is small or random — ordinary packet loss or a flaky link; the pool is not the cause.

agentty seems stuck after Esc

Fixed in current builds — a cancelled worker thread could null out a new turn's cancel token. Update to the latest release. If you still see it, restart the process and file a bug with your git rev-parse HEAD (or release version).

Starting a new thread (^N) or switching threads while a reply is streaming stops that reply and any tools it was running. Nothing from it lands in the thread you switched to.

Certificate / TLS verification errors

You're likely behind a TLS-terminating proxy. Install the proxy's CA into the system trust store — see Corporate Proxies. As a last resort, AGENTTY_INSECURE=1 skips verification (not for shared use).

Auth not picked up

Check which source agentty will use:

agentty status

Remember the override order: --key > ANTHROPIC_API_KEY > CLAUDE_CODE_OAUTH_TOKEN > on-disk credentials. An env var will shadow the credentials file.

Air-gap connection fails

  • Confirm OpenSSH ≥ 7.6 on both ends.
  • Make sure agentty is on the remote PATH, or pass --remote-agentty PATH.
  • Run --setup once so credentials are copied to the remote.

A local model (llama.cpp / vLLM) won't respond

agentty now diagnoses this instead of looping. The usual causes:

  • The spec is missing /v1. Most local servers only serve under /v1. A bare localhost:8080 gets the /v1 prefix automatically, but a partial path like localhost:8080/api is honoured verbatim and will 404. Use the picker (^P → Custom host) so the derived path shows in the connect toast, or check with AGENTTY_LOG=wire=trace.
  • The model id doesn't match the server. llama-server serves exactly what its /v1/models reports (often the GGUF filename). If a recalled id isn't listed, agentty refuses with “model X isn't served by this host — pick one (^/)” — open ^/ and pick a listed model.
  • A chat-template rejection. Some models (gemma, gpt-oss) reject agentty's system prompt/tools with a streamed error. agentty surfaces the server's actual message; run AGENTTY_LOG=wire=trace to see the exact request and rejection.
  • Slow, not stuck. A big model can process the prompt silently for minutes; the phase chip reads “processing…” and the timeout is 10 minutes for local endpoints. That's expected — Esc cancels if you don't want to wait.

See Providers › Custom hosts for the full model.

HTTP 429 / “quota exceeded”

A 429 means one of two things, and agentty tells them apart by how long the provider says to wait:

  • A short wait (a burst or per-minute limit): agentty waits the time the provider asked for and retries on its own. The status bar counts the attempts.
  • A wait of more than 15 minutes (a daily or plan quota): agentty shows the error straight away. Retrying can't work until the quota resets, so it doesn't make you sit through it.

The wait comes from the Retry-After header, or from the error body when the provider puts it there instead. Google Gemini does the latter ("retryDelay": "6043s", “Please retry in 1h40m”).

To get going again, wait for the reset, add billing or credit with the provider, or switch model (^/) or provider (^P). On Gemini's free tier, limit: 0 in the message means that model gets no free requests at all. See Providers › Google Gemini.

“this model can't read images — retried without them”

The provider rejected a request because of an image in it: the model has no vision, the format isn't supported, there are too many images, or your organisation disabled image input. agentty removes the images from the request and sends the turn again, so you still get an answer about the text. This covers images you pasted and images a tool returned, such as read on a .png. Your transcript keeps the images; only the request loses them.

If you need the image read, switch to a vision model (^/).

A local model refuses (“I can't do all of that in one reply”)

Small local models sometimes refuse a big task instead of working through it. agentty's local prompt tells them to work step by step with tools and never refuse for size (see Providers › The prompt local models get), but a model around 20B parameters can still give up on a long spec. Ask for one part at a time (“create the login screen”, then “add the settings screen”), or use a bigger model.

“wait for the thread to finish loading”

You pressed Enter while a thread was still loading or a checkpoint rewind was running. agentty holds the message instead of sending it into the thread you're leaving. Your draft stays in the box; press Enter again once the load finishes.

Turning on logs for a bug report

AGENTTY_LOG=debug agentty --log-file /tmp/agentty.log
# reproduce, then attach /tmp/agentty.log

For a provider/wire problem add AGENTTY_LOG=wire=trace to capture the raw request/response bytes. If agentty crashed, the stderr output already includes a backtrace and the last ~256 events (the flight recorder). Full details: Logging & diagnostics.

Ctrl+V pastes text instead of my image

Your clipboard lives on the machine your terminal runs on, so over SSH agentty has to ask the terminal for it. Only kitty can send image bytes back (OSC 5522); every other terminal answers a text-only dialect (OSC 52), which is why the paste arrives as prose.

On kitty this is almost always one setting — its clipboard_control defaults to write-only, so reads are refused:

# ~/.config/kitty/kitty.conf   (on the machine kitty runs on)
clipboard_control write-clipboard write-primary read-clipboard read-primary

Restart kitty fully. Inside tmux also run tmux set -g allow-passthrough on (off by default), or the request never reaches kitty.

On any other terminal, attach by path (@shot.png) or set AGENTTY_CLIPBOARD_CMD to ferry the clipboard over SSH. Full setup, including the Linux wl-clipboard / xclip requirement and a troubleshooting table: Clipboard & Images.

agentty is using a lot of disk, or settings/history won't save

Run agentty config to see every folder agentty uses and its size, and agentty config doctor to check each one is writable and private. Conversations are usually the bulk: move them with agentty config move threads /some/big/disk (then add the export line it prints), or expire old ones with AGENTTY_THREADS_KEEP_DAYS=90. agentty config clean lists files older versions left behind. See Storage.

Garbled rendering

Some terminals lag on DEC 2026 synchronized output. File a bug with your $TERM, the terminal emulator name, and a screenshot.

ℹNoteFound something not covered here? Open an issue with $TERM, your emulator, the version, and a screenshot or paste of the relevant block.