§08Reference

Troubleshooting

Start with chi doctor. It changes nothing, it names the problem, and it is right more often than a guess.

§01

First, in every case

$ chi doctor

It inspects the installation and says what is wrong with it, and it changes nothing — which is what makes it safe to run when confused, the only time anybody runs it. Three narrower reports go deeper: chi doctor agents for whether Archis is in front of a model, chi doctor crypto for encryption, chi doctor versions for every version stamp in the build.

§02

chi: command not found

The binary installed somewhere that is not on your PATH. The installer says so when it happens, and the fix survives a new terminal only if you put it in your shell profile:

$ export PATH="$HOME/.local/bin:$PATH"
$ chi --version

If chi works but your agent reports that the server cannot start, the missing one is chi-mcp — installed alongside it and launched by the agent rather than by you. Both must be reachable by the agent's own environment, which is not always your interactive shell's. chi agents check <id> catches exactly that.

And if the file is plainly there, executable, and the shell still says not found, the missing thing is not chi — see the next section.

§03

Alpine, musl, and containers

Five builds are published — darwin-arm64, darwin-x86_64, linux-x86_64, linux-arm64, windows-x86_64 — and both Linux builds are linked against glibc. There is no musl build. On Alpine the file installs, is executable, and the shell still reports not found: what is missing is the dynamic loader, not the binary.

$ ldd $(command -v chi)
/lib/ld-linux-x86-64.so.2 => not found

Three ways out, cheapest first:

  • Use a glibc base image. debian:*-slim or ubuntu:* costs a few tens of megabytes and is the path the published builds are tested on.
  • Add the compatibility shim. apk add gcompat is one command and usually enough for a CLI with no exotic libc use. It is a workaround, not a configuration we test, so it can regress on an Alpine upgrade without anything on our side changing.
  • Ask us for a musl build. Archis is distributed as signed binaries, not as source, so building it yourself is not an option. If neither of the above works for your image, open a support ticket with the image you use and we will tell you where a musl build stands.

In a container, mount the repository read-write. Archis writes its graph to a .chi directory beside the code, and a read-only mount fails at the first index rather than at run time. A volume also keeps the graph across docker run invocations, which is the difference between indexing once and indexing every time.

§04

The agent still reads files

The most common report, and usually not a bug: the tools are registered and the model was never told to prefer them. Work through it in this order.

CheckCommandWhat a good answer looks like
Is Archis connected at all?chi agentsYour harness listed as installed, connected and briefed.
Does the connection work?chi agents check <id>All six checks pass, including the live tool call.
Is the model being told?chi agents adviceArchis speaks up before the agent reaches for its own file tools.
Did it change anything?chi tools discoverTool-output spend falling across recent sessions.

If advice reports nothing, the briefing is missing or was edited out of your instructions file. chi agents on <id> writes it again. For harnesses with no session hook, the instructions file is the only channel, so it is worth checking that the file is one the harness actually reads at the scope you expect — project or user. See Telling the model.

§05

chi agents check fails

The check reports which of the six steps failed, and each one has one cause.

  • CLI not installed — the harness itself is not on PATH. Nothing to do with Archis.
  • Not registered — the harness does not list chi among its servers. Run chi agents on <id>. If your Goose or OpenCode config contains comments, Archis refuses to rewrite it and prints a snippet for you to paste instead — that refusal is deliberate, because no round trip preserves comments.
  • Server binary missing — chi-mcp does not resolve. See above.
  • Handshake or tools failed — the registered command line does not run. Reinstall over it with chi agents on <id>, which rewrites the entry with a resolved path.
§06

The server starts and nothing comes back

MCP over stdio is two pipes and a JSON frame per line. Your harness starts chi-mcp itself, so when that fails you see the harness's version of the story — "server exited", "no tools", a timeout — and none of them name the cause. Ask the pipe directly instead, with no harness in the way:

$ printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}\n' | chi-mcp
{"id":1,"jsonrpc":"2.0","result":{"capabilities":{"tools":{}},…

A JSON object on stdout means the pipe and the binary are both fine and the problem is registration — back to chi agents check <id>. Lines about the graph, the licence or which agent connected are stderr, they are expected, and they are not part of the protocol.

What you seeCauseFix
Permission deniedThe execute bit is not set — a tarball unpacked under a strict umask, or a copy made by a tool that drops the mode.chmod +x ~/.local/bin/chi ~/.local/bin/chi-mcp
Permission denied with the bit setThe filesystem is mounted noexec — common for /tmp, network shares and some container volumes.Install under your home directory instead, then re-run the check.
macOS: killed, or "cannot be opened"Gatekeeper quarantine on a manually downloaded copy. The installer's binaries are signed and notarised and never hit this.xattr -d com.apple.quarantine ./chi-mcp
The harness reports a parse or protocol errorSomething else is writing to stdout. It belongs to the protocol, and one stray line corrupts the first frame.See the warning below.
stderr: skipping non-JSON lineArchis received something that is not a frame. It says so and carries on, so this is a report about the other end, not a failure of Archis's.Look at what the harness is sending — usually a wrapper's own output.

One more environment trap: the harness launches the server from its own environment, not your shell's, so a path that works when you type it can still be unresolvable there. chi agents on <id> writes the entry with an absolute, resolved path, which is the fix for every version of that.

§07

Answers look stale, or a symbol is missing

Start with the one command that says whether it is stale at all:

$ chi status
14 files changed since the last index (2 added, 12 changed, 0 removed) — `chi index` picks them up.

Its last line is the answer. Files changed since the last index means the graph has drifted from the tree and chi index closes the gap. If it reads The graph matches the tree — nothing to index, the cause is one of the other three, in order of likelihood:

$ chi index path/to/changed-file.ts
re-reads one file without rebuilding the graph
$ chi status --lang python
is this language understood at the layer you are asking about?
$ chi index --detect
what is actually being found here — writes no graph

A symbol that never appears is usually a scope question rather than a parse failure: the file may be excluded by .chignore, or live in a directory the default scope skips — dependencies, build output, hidden directories. chi index --no-prune includes all of it, at an order of magnitude more work.

If the language is supported at a shallower layer than the question needs, that is a real limit rather than a misconfiguration, and chi status --coverage quantifies it. Files nothing can parse can still be made findable with chi index --detect --opaque.

§08

The first index is slow

It runs on your hardware, which is the consequence of an index that never leaves it. Three things actually help:

  • Do not pass --no-prune unless you need it. It adds dependencies, build output and hidden directories, which is where most of the time goes and where almost none of the value is — an order of magnitude more work, which is why it is asked for rather than assumed.
  • Add a .chignore for generated code, fixtures and vendored trees. Same spirit as .gitignore.
  • Index the part you are working on first. chi index ./services/api is a useful graph in a fraction of the time, and the rest can follow.

chi index --timings reports per-stage timings if you want to know where it went rather than guess.

§09

A multi-gigabyte monorepo

Nothing here is a special mode — it is the ordinary flags, used in the order that keeps a repository of that size from being a single all-day command. The plan: look before you index, index one area, then let the incremental pass carry it.

1 — find out what is actually in there
$ chi index --detect
languages found, and how deeply each one is understood

It writes no graph. In a monorepo this is where the surprises are: a vendored third-party tree nobody remembers, a few hundred megabytes of generated clients, fixtures larger than the code. Those belong in .chignore before the first real pass, not after it.

2 — index one area, not the tree
$ chi index ./services/checkout
$ chi index ./libs/shared

One graph, grown a subtree at a time. A partial graph is useful immediately — an agent asking about services/checkout does not care that services/billing is not in yet — and each pass is short enough to run between other work rather than being scheduled.

3 — after that, only what changed
$ chi status
$ chi index

The full pass happens once. From then on chi index updates the files that moved, and chi status tells you how many that is before you run it. When the MCP server is connected it also checks the tree before answering, so in normal use nobody runs chi index by hand at all.

Two things to watch on disk and in review. The graph lives in a .chi directory beside the code and grows with the repository, so a machine with a nearly full disk will fail mid-index — chi doctor reports the index's location and size, and is worth a look before the first pass on a big tree. And .chignore is part of the repository: in a monorepo it is the shared answer to "what is not worth indexing", so it belongs in review like any other file rather than in each developer's working copy.

§10

Licence problems

$ chi auth status
$ chi auth refresh

status says what the entitlement grants and until when, and it works offline — the licence is a signed document verified locally. refresh forces an online validation now rather than waiting for the scheduled one, which is the fix after a plan change or a payment that has since gone through.

If a machine has been offline long enough for its grace window to lapse, chi auth login re-activates it as soon as it has a connection. The account portal shows which devices are currently activated, and is where to release one you no longer use.

§11

The index will not open

Expected, and by design, in one situation: the index was created on a different machine. It is sealed with a key that machine generated and never sent anywhere, so a copied, restored or synced .chi directory is unreadable elsewhere.

$ chi doctor crypto
$ chi keys status

The fix is to rebuild it locally — chi index — which costs time and nothing else. If the index also predates a licence epoch change, chi keys rotate re-wraps it under the newest epoch your licence carries. For a machine that must open an index without a licence at all, chi keys passphrase is the bring-your-own-key path. Details in Index encryption.

§12

Opening a ticket

Because your repository never reaches us, we cannot reproduce anything from our side. What makes a ticket answerable in one round trip:

$ chi doctor --json > doctor.json
$ chi doctor versions
  • The output of both commands above.
  • The exact command you ran, and what it printed.
  • Which harness, and its version.
  • Whether chi agents check <id> passes.

Open a support ticket → (it needs you signed in), or email [email protected]. Attach your doctor.json: it is usually everything we need to answer in one reply.