Kotoba

Where to start

What Kotoba isWho she is and where she runs, in one page
InstallingOne package, two commands
First runA key, a model, her first words
The approval gateHow she asks before she acts
The two voice modesLocal voice, or the agent tunnel
The soul fileChange who she is
RoadmapWhat grows next, and what was cut on purpose

Or a section

↑↓ move openesc close124 pages
All pages

Start7 of 7

Troubleshooting the first hour

About 7 minutes to read

On this page

Run kotoba doctor first. It is designed for exactly this and it names most of what follows. These are the cases where the report is not enough, or where the message you see needs translating.

She answers, but she has no brain

"I'm here, but my language model isn't connected yet — run kotoba setup and I'll be able to think properly."

That is the loop's offline reply. There is no usable model key. kotoba doctor will show fail on llm key and name the fix.

Three things read as "no key": nothing set at all, a key the master key can no longer decrypt, and the placeholder from api/.env.example (sk-..., el_...). The placeholder is rejected deliberately, so an unedited example file fails with a sentence instead of a 401 nobody sees.

kotoba doctor says a saved key cannot be decrypted

The master key changed or was lost. It lives at ~/.kotoba/.keystore_key unless KOTOBA_MASTER_KEY is set. Every affected secret is listed by name — the model key, the ElevenLabs key, MCP credentials — and each has to be entered again. None can be recovered. Run kotoba setup for the model and voice keys.

If you moved your home directory or set KOTOBA_HOME after your first run, point it back before you re-enter anything.

The key is fine but every turn comes back empty

Check the llm key row for a model mismatch. provider and model are two separate settings, and abandoning a first run between them can leave one provider selected with the other's model. The row says so explicitly, naming the model and which provider does serve it. Fix it with kotoba setup or /set model in the terminal.

She has no face

The avatar area says:

No Live2D model is installed yet, so she has no face — Settings → Brain → Run setup again, then walk to Her face, or unpack a Cubism 4 model into its own folder under ~/.kotoba/models and reload. Calls, chat and work all still run.

Nothing ships one, on purpose. See Requirements. If you set her up from the terminal, the first visit to /app offers the face step once; after that the way in is Settings.

A different message — "Her avatar didn't load — the model is installed but something in it failed to fetch or parse" — means a model is there but incomplete. The browser's Network tab names the file that 404s. A model whose entry file sits more than two folders deep is not found at all.

The call connects but she never speaks

The most common cause is no ElevenLabs key, or one ElevenLabs rejected. The notice you get is the same either way:

ElevenLabs rejected the API key, so she can't hear you. Check your ELEVENLABS_API_KEY, then start the call again.

Read that as "the voice key is missing or not accepted". kotoba doctor's voice key row tells the two apart: it says whether a key is present at all and where it came from.

Other voice messages and what they mean:

NoticeCause
"This browser only allows the microphone on HTTPS or localhost"You reached the page over plain HTTP from another machine. Browsers refuse a microphone on an insecure origin
"The browser blocked the microphone"Site permission denied. The icon by the address bar
"No microphone was found" / "another app may be using it"Device problem, not a Kotoba problem
"The ElevenLabs quota is used up"Add credit; the key itself is fine
"The voice connection was refused before it opened"The backend only accepts the page origin it knows. If you moved the web port, add that address to CORS_ORIGINS and restart

Her voice is flat and the [tags] are never performed

kotoba doctor says this on the voice tags row. expressive is on while the fast TTS engine strips every audio tag before synthesis — so her face keeps emoting and her voice does not. Set tts_engine to expressive in Settings, or turn expressive off if the flat voice is what you wanted.

The port is already in use

kotoba serve does not swallow this. You get uvicorn's own line and then a clean stop:

[api] ERROR:    [Errno 98] error while attempting to bind on address ('127.0.0.1', 8000): address already in use
stopping — [api] exited with 3

Both children come down together, so nothing is left holding the other port. Move it:

bash
kotoba serve --port 8080 --web-port 3100

npm run dev forks a worker that outlives npm, which is why kotoba serve puts each child in its own process group and signals the whole group. A process ended some other way can still leave that worker holding port 3000.

The UI does not load

kotoba doctor's web ui row answers this in one line. Four shapes:

  • ok … packaged build, N files — the backend serves it itself at /app on the backend port. You are looking at the wrong address if you are on 3000.
  • ok dev server — you are in a clone with npm, so the app is on the web port (3000 by default), not on /app.
  • warn no build, and no dev server either: … — the message names the missing piece. In a clone it is usually npm install not having been run. kotoba serve prints the same reason as [web] not started: ….
  • fail this install carries no web UI — reinstall with pip install --force-reinstall.

/ redirects to /app on both. On an unconfigured install /app redirects to /setup.

Everything returns 401

You set KOTOBA_WEB_PASSWORD on one process and not the other. When the Next frontend runs as its own process it needs the same value in its own environment. Both sides also accept the older name KOTOBA_GATE_PASSWORD, so either spelling works — what has to match is the value, in both environments.

The login screen accepts the password and comes straight back

The browser dropped the session cookie. It is marked Secure when the request arrived over HTTPS, and a browser refuses a Secure cookie on an http:// page — the password is accepted, the redirect goes through, and you land back on the login screen.

Kotoba reads X-Forwarded-Proto (or X-Forwarded-Scheme) and falls back to the request's own scheme, so any proxy that sends that header is handled without configuration. If yours does not send it, make it — nginx, for instance, needs proxy_set_header X-Forwarded-Proto $scheme; written out.

kotoba prints an install command and exits

No module named 'prompt_toolkit'.  pip install "kotoba-companion[cli]"  — or use --once

The interactive terminal is the cli extra. kotoba --once "…", setup and doctor work without it. kotoba serve names kotoba-companion[server] the same way.

kotoba on Windows starts a web server instead of a terminal

That is deliberate. Her interactive terminal is built on the POSIX terminal layer (termios, tty), which Windows does not ship, and the cli extra cannot supply it. So bare kotoba starts the backend and the web UI, says it is doing that, and opens your browser once the web UI answers. Ctrl+C stops both.

setup, doctor, serve, discord and --once are native there. kotoba doctor reports it on the terminal row.

One more Windows difference worth knowing early: almost no approval is remembered there. "Always allow this line" never persists, and "always allow this command" does not either for anything typed as a shell command, so those ask every time. The analysis behind a grant is written for POSIX shells while PowerShell is what runs; rather than guess, it keeps asking.

A flag was refused instead of ignored

kotoba: --calm does nothing on `kotoba doctor`. Nothing on that report moves, and it has no face to leave out.

Exit code 2. Each subcommand acts on the render flags it really can act on and refuses the rest by name, whichever side of the subcommand you typed them. setup takes all four; doctor takes --plain and --ascii; serve and discord take none.

An MCP server will not connect

kotoba doctor connects each saved server as part of its report, so a stdio server that dies on startup fails there and nowhere else. The last row of that section names the log file holding what each one printed while starting.

A missing ~/.kotoba/mcp.yaml is not the cause: when that file is absent the loader reports no servers rather than failing. It is written when you install a server.

Nothing above matches

Two files worth reading yourself:

bash
cat ~/.kotoba/cli.log                  # her log
curl http://127.0.0.1:8000/health      # → {"status":"ok"}

Every tool call whose declared risk is write, exec or network is also recorded in a local audit table, along with every approval decision and who made it. No HTTP route exposes that table; read it yourself:

bash
sqlite3 ~/.kotoba/kotoba.db "select * from audit_log order by created_at desc limit 20"

From a clone the database is at api/kotoba.db instead.