Skip to content

Troubleshooting

Common problems and what to do about them.


Expected, and recoverable. The app is ad-hoc signed but not notarised — that needs a paid Apple Developer certificate — so macOS blocks the first launch. Open System Settings → Privacy & Security, find the line about Agento, and click Open Anyway.

If that line is not there:

Terminal window
xattr -dr com.apple.quarantine /Applications/Agento.app

Only the first launch needs this. Updates the app installs itself are not quarantined, so they never ask again.

macOS says the app is damaged and should be moved to the Bin

Section titled “macOS says the app is damaged and should be moved to the Bin”

This is a different message, and it means the download predates the release that added ad-hoc signing. Those builds were not signed at all, and on Apple Silicon the linker’s own bare signature sealed nothing — Gatekeeper reads an invalid seal as “damaged”, which deliberately offers no Open Anyway.

Download the current release and install it over the old copy. If you would rather keep the copy you have:

Terminal window
xattr -dr com.apple.quarantine /Applications/Agento.app

Either way it is once; the app then updates itself normally.

Click More info, then Run anyway. The installer is not code signed, so SmartScreen has no publisher to recognize.

Most often a missing FUSE library. Either install it:

Terminal window
sudo apt install libfuse2 # Debian, Ubuntu

or run without it:

Terminal window
./Agento_1.0.0_amd64.AppImage --appimage-extract-and-run

Also check the file is executable: chmod +x Agento_*.AppImage.

Your package manager could not find GTK 3 or WebKitGTK 4.1. That usually means the distribution release is older than WebKitGTK 4.1. Use the AppImage instead.

Your system’s webview is too old or missing.

  • Linux: install libwebkit2gtk-4.1-0.
  • Windows: install the WebView2 runtime. The installer normally handles this.

Restart the app after installing.

It is probably already running. Agento allows one copy at a time, and a second launch focuses the existing window instead of opening a new one. Check your dock, taskbar or window list.


“Agento could not find the Claude Code CLI”

Section titled ““Agento could not find the Claude Code CLI””

Agents run by launching claude. Agento resolves which binary that is once per launch, in this order — the first hit wins:

  1. AGENTO_CLAUDE_EXECUTABLE, if it is set.
  2. Settings → Claude → Claude Code CLI → Executable, if you have filled it in.
  3. Your login shell — Agento runs $SHELL -lic 'command -v claude'.
  4. Every directory on the PATH the app itself was launched with.
  5. The known install locations: ~/.local/bin, ~/.claude/local, /opt/homebrew/bin, /usr/local/bin, ~/.nvm/versions/node/*/bin, fnm’s and asdf’s directories, ~/Library/pnpm, ~/.yarn/bin, ~/.bun/bin, ~/.volta/bin, ~/.npm-global/bin, ~/bin, and AppData/Roaming/npm on Windows.

A candidate found by 3, 4 or 5 has to answer --version like Claude Code, so an unrelated program of the same name on your PATH is skipped rather than run for every chat.

Step 3 exists because a GUI application does not inherit your shell’s PATH. An app launched from Finder, the Dock or Spotlight on macOS gets launchd’s /usr/bin:/bin:/usr/sbin:/sbin and nothing your .zshrc ever exported; a .desktop launch on Linux is only a little better. It is also the only step that can see an install made with claude migrate-installer, which puts the binary in ~/.claude/local and wires it up as a shell alias — so there is no binary on any PATH at all.

First check it works in a terminal:

Terminal window
claude --version

If that works and Agento still says it cannot find it, open Settings → Claude and paste the path into Executable. which claude gives you the path; if it prints an alias rather than a path, use the path from the alias. Restart Agento afterwards — resolution happens at launch.

The same pane shows what Agento did find and which of the five steps found it, which is what to read when the CLI it picked is not the one you expected.

AGENTO_CLAUDE_EXECUTABLE=/full/path/to/claude still works and still wins over everything, including the setting — but note that on macOS an app launched from the Dock cannot see a variable you exported in a shell, so the Settings field is usually the one you want.

Agento does not manage Claude authentication. Sign in with the CLI:

Terminal window
claude

Complete the sign-in there, then retry in Agento.


Click Stop. If the composer is still blocked afterwards, reload the transcript from the toolbar.

If it keeps happening, check the log for the run. A claude subprocess that crashed ends the stream with nothing to say why, and the log is where the reason lands.

Tools are an allowlist. Open the agent and confirm the tool is ticked. For integration tools, also confirm that integration’s service is enabled and that its credentials are still valid.

Check the chat’s working directory. An agent only reaches the folder the chat was started in.

Asking is the default in a chat, because you are there to answer. Each chat carries its own permission mode, so to stop the prompts for a conversation you trust, start it with Permissions → Never ask.

The setting is chosen when the chat is created and the inspector shows what a chat is running under. Existing chats keep whatever they were created with; chats created before this setting existed fall back to the agent’s mode, and to asking if the agent has no preference.

Unattended runs, meaning scheduled tasks, never prompt, because nothing could answer.

If a tool is denied without any prompt at all, it is not on the agent’s tool list. Add it there — the allowlist is enforced whatever the permission mode says.


If it says “Scanning” with a count, the first index is still running. Wait for it.

If it says there are no sessions, Agento found no Claude Code history where it looked. Check Settings → Claude → Indexed directories covers the directory your transcripts are in. The default is ~/.claude.

Sessions from a second Claude account are missing

Section titled “Sessions from a second Claude account are missing”

Add that account’s configuration directory in Settings → Claude → Indexed directories. Both accounts then appear in every total.

Check Settings → Data → Hidden projects. Unhiding is immediate and costs nothing.

Cost is computed from the price catalog in Settings → Pricing, at the price in effect when each message was sent.

  • A model with no entry contributes no cost, and the totals say how many tokens were unpriced.
  • If a price in the catalog is wrong, use Correct a rate, not “add a rate”. Correcting rewrites history; adding only affects messages after that date.

Either way, sessions re-price in the background afterwards. It can take a few minutes on a large history.

They are meant to. Duration means active time, not the span from first to last message. A session resumed a week later would otherwise report a week. Adjust the threshold in Settings → Data → Idle gap threshold.

Some changes invalidate every stored figure and force a full re-read: a price edit, and a change to the idle gap threshold. That is expected, it runs in the background, and the app stays usable.


Check, in order:

  1. The task is Enabled.
  2. The inspector shows a Next run in the future.
  3. Stop after has not been reached and Stop at has not passed.
  4. Agento is actually running. A desktop app that is closed fires nothing.

Two Agento processes are sharing one data directory. Agento normally prevents a second copy from starting, so this means one of them was pointed at the same directory deliberately with AGENTO_DATA_DIR. Close one, or give it its own directory.

The run took longer than the task’s Timeout. Raise it, or make the prompt narrower.


Re-enter them. Agento asks for credentials again when you edit an integration that has stored ones, because saving the form without them would wipe the working credential.

Close the browser window and try Connect again. If your browser blocked the redirect to a local address, allow it and retry.

Tools from an integration are not offered to an agent

Section titled “Tools from an integration are not offered to an agent”

Three things have to line up: the integration is connected, the service is enabled inside it, and the tool is ticked on the agent.

Agento does not support WhatsApp. An integration created by an older version is still listed and its data is safe, but it cannot be edited or used.


Something else already holds that port. Change it in LLM Gateway → Gateway Settings → Port and save; the listener rebinds immediately.

The Settings form now checks the port as you type and offers a free one — “Port 8880 is already in use by another process. Port 8881 is free.” — so this state is usually avoidable. It is still only a check, not a reservation: something can take the port between the check and the bind, and this status is the authority on what actually happened.

The usual culprit is a second Agento. A development build and an installed one read different databases but share the machine’s ports, so both can be configured for 8880 and only the first to start gets it. The status carries the exact reason, and the same line is in the log:

binding the llm gateway on 127.0.0.1:8880: Address already in use (os error 98)

“Enable the gateway” is greyed out and will not turn on

Section titled ““Enable the gateway” is greyed out and will not turn on”

The gateway has nothing to route to. Both Enable the gateway and Start with the app stay shut until there is at least one provider and at least one model alias — without both, the listener would bind a port that fails to route every model name a client sends, which is the mismatch below with nothing to mismatch against.

The message beside the switches says which of the two is missing and links to it. Add it, come back, and the switches are live; nothing needs restarting.

Two things it is not. It never turns a gateway off: an install that was already enabled keeps its switch usable in the off direction, so deleting your last alias does not lock you out of stopping the listener. And it never blocks Save — a retention or port edit still saves while the switches are shut.

If it instead says “could not check whether the gateway has anything to route”, the providers or aliases read failed rather than coming back empty. The switches are held for the same reason, and the message carries the underlying error.

“Check these credentials” says the key is refused, or the provider is unreachable

Section titled ““Check these credentials” says the key is refused, or the provider is unreachable”

LLM Gateway → Providers → Check these credentials asks the provider to list its models, which authenticates the same credential a real request would. What it answers means:

  • Key refused (401/403) — the key is wrong, revoked, or out of credit. Some providers report an exhausted plan as 403 rather than 429, so a key that worked yesterday can land here. Re-issue it and use Replace key.
  • Unreachable — nothing answered at the Base URL, or it answered 404. That is the base URL rather than the key: a 404 means the address is not this provider’s API root. Leave it empty to use the provider’s own endpoint, except on GLM, which requires one.
  • Unexpected — the provider answered something else, and the status is shown beside the verdict. A 5xx is usually theirs rather than yours.

The check never sends your key anywhere but the provider, and no answer, log line or error message carries it back. That is also why changing Type on a provider that already has a key refuses with “the stored key belongs to a different provider type” rather than checking: the stored key is that vendor’s, and the new type decides which vendor it would be sent to. Enter the key for the type you have selected.

It can be wrong in one direction, and Save anyway is the answer. A base that serves completions but no model list — a proxy, something self-hosted, some OpenAI-compatible vendors — cannot produce a green verdict however correct the key is. Save anyway is beside Save for exactly that, and nothing is ever blocked behind a check.

Editing a provider asks for the API key I no longer have

Section titled “Editing a provider asks for the API key I no longer have”

It no longer does. A provider with a key stored shows ••••••••••• stored and saves without one — the save simply sends no api_key field, and the server keeps what it has. Replace key is what puts the input back on screen.

On a build predating that change the form did require a re-typed key on every save. There is no way to recover the stored one — it is write-only by design — so either update, or issue a new key at the provider and paste that in.

LLM Gateway → Models fills a target’s model box from that provider’s own catalog, and shows a note under the row when it could not. It never blocks the save — type the id and carry on. The note says which of these it was:

  • No API key — the provider row has none stored, so there is nobody to ask. Set it in LLM Gateway → Providers.
  • The provider answered 401 / 403 — the key is wrong, revoked, or not entitled to the list endpoint. The same key is what serving a request would use, so this is worth fixing whatever the model box does.
  • The provider could not be reached — a wrong base URL, no network, a proxy, or an upstream that is simply slow; the fetch gives up after ten seconds.
  • The answer was not a model list — the base URL points at something that is not that provider’s API. Check it against Providers.
  • No models returned — the account is authenticated but the catalog is empty, which usually means a project or region with nothing enabled on it.

The list is fetched when you open the Models view, not when you save, so a slow provider never delays a save. It is not cached between visits: fix a key in Providers and come back to this view to see the list.

The token is absent, malformed, expired, revoked, or was signed by a key this install no longer uses — regenerating the signing key does that to every token at once. Mint a new one from LLM Gateway → Overview and paste it into the tool again.

Check the tool is actually sending it: the gateway accepts either Authorization: Bearer <token> or x-api-key: <token>, and an Authorization header that is present but not a Bearer is ignored in favour of x-api-key.

You used a read or write token. Those reach the Agento API and are refused here on purpose. Mint one with the llm scope — Overview’s Create gateway token button does exactly that — and use it instead.

A bigger Agento token is not the fix. The scopes are disjoint rather than ranked, so write does not include llm.

The Agento API answers 403 for a token that works on the gateway

Section titled “The Agento API answers 403 for a token that works on the gateway”

The same rule the other way round. An llm token reaches the gateway and nothing under /api; there is no Agento API route that accepts one. Use a read or write token for the API.

The tool connects but every request fails with a model error

Section titled “The tool connects but every request fails with a model error”

The name your tool sends as model has to be an alias you defined, exactly. There is no prefix parsing and no fuzzy matching, so an unconfigured name is a 404:

model alias 'claude-opus-5' is not configured on this gateway

For Claude Code this is the default first experience, because it asks for its own default model unless told otherwise and stops with “There’s an issue with the selected model”. Either export ANTHROPIC_MODEL=<your alias>, or name an alias after the model Claude Code asks for.

Check the base URL has no /v1. Claude Code and the Anthropic SDK append /v1/messages themselves, so ANTHROPIC_BASE_URL ends at /anthropic:

Terminal window
export ANTHROPIC_BASE_URL=http://127.0.0.1:8880/anthropic # right
export ANTHROPIC_BASE_URL=http://127.0.0.1:8880/anthropic/v1 # 404 on every call

The OpenAI-shaped base URL is the opposite and does end in /v1.

A row is written per request the gateway served, so a request refused before it got that far — a bad token, a 404 on the base URL — records nothing on purpose. Confirm the listener is up and the request is arriving:

Terminal window
curl http://127.0.0.1:8880/healthz
curl http://127.0.0.1:8880/v1/models -H "Authorization: Bearer <your gateway token>"

/healthz needs no credential. /v1/models lists your aliases; if the alias you expect is missing or disabled, that is why traffic is not reaching it.

Cost is computed from the price catalog, which ships filled in for Anthropic, Moonshot, Z.ai and Alibaba models — so OpenAI and Gemini traffic has no rate. Anything unpriced is recorded as such rather than as free, which is why the total is labelled a floor. Add rates under Settings → Pricing for the models you actually use.

The same Agento.log as everything else — see Reading the logs. Gateway lines are prefixed llm gateway or gateway:

llm gateway listening on http://127.0.0.1:8880
gateway completion streaming alias=fast provider=my-openai model_id=gpt-4o-mini
gateway usage pruned rows=1204 older_than_days=90

The app says an update is available but there is no install button

Section titled “The app says an update is available but there is no install button”

You installed from a .deb or .rpm. Those are notify only, because your package manager owns the installed files. Download the new package and install it the way you installed the first one, or switch to the AppImage for in-app updates.

Not below 0.1.1. That release added a database column, and Agento refuses to write to a database newer than itself rather than corrupting it — so an older build would appear to fail on every action.

Your data is not damaged by this. If you need an older build, restore the ~/.agento backup you took before upgrading.

Check your network and try again from About → Check for updates. Updates are downloaded from GitHub, so a proxy or a firewall that blocks it will stop them.

If it keeps failing, download the release manually and install over the top. Your data is untouched by a reinstall.

Settings → General → Updates → Never check.


Platform Path
Linux ~/.local/share/com.shaharialab.agento/logs/Agento.log
macOS ~/Library/Logs/com.shaharialab.agento/Agento.log
Windows %LOCALAPPDATA%\com.shaharialab.agento\logs\Agento.log

The live file plus three dated archives are kept, roughly 20 MB in total.

The log records one line per API request, plus what each write did. It does not record message bodies, prompts, credentials or search terms. It does record agent slugs and file paths, so treat it as mildly sensitive when sharing.


Open an issue at github.com/shaharia-lab/agento/issues with:

  • Your platform and how you installed (dmg, exe, AppImage, deb, rpm).
  • The Agento version from About.
  • claude --version.
  • What you did and what happened.
  • The relevant lines from the log.