Common failure modes and the fixes that actually work.
The env var that embedding.api_key_env points at has to be set in the
environment of whatever process is running lilctx. The shipped default is
LILCTX_OPENROUTER_API_KEY; if you set LILCTX_OPENAI_API_KEY instead, the
override layer flips api_key_env to that name automatically.
For an interactive shell, export LILCTX_OPENROUTER_API_KEY=.... For Claude
Code, put it in the env block of the MCP server entry — the spawned
process does not inherit your shell environment.
You exported both. Pick one. They're mutually exclusive because each one
controls which base_url the embeddings client points at, and we'd rather
hard-fail than silently pick a winner.
The model the API actually used returned a different vector size than your config promised. Either:
- You changed
embedding.modelwithout updatingembedding.dim. Update it to match what the model produces. - The provider silently routed you to a different model. Check their docs.
After fixing the config, delete data_dir and reindex. LanceDB fixes
the vector column type at table-creation time, so a stored table with a
different dim cannot be reused.
Almost always a dim mismatch between config and the stored table. Same
fix: delete data_dir, confirm embedding.dim matches the model,
reindex.
The lancedb and arrow-array crates are version-locked to each other.
If you bumped one and not the other, you get errors like this. Bump them
together — see the pin notes in Cargo.toml.
lilctx index logs to stderr at info level by default. Crank verbosity:
RUST_LOG=lilctx=debug lilctx indexIf embedding is slow on a cold reindex, that's expected — embedding is the bottleneck and the calls are serial across files today. See the "where things commonly need fixing" section in Architecture.
Your editor's save burst is exceeding the 500ms debounce window. Bump
DEBOUNCE_MS in src/watch.rs and rebuild. Don't add a second layer of
dedup — the existing file_hash skip will already make the second pass
cheap, but a longer debounce is cleaner.
In rough order of likelihood:
- The MCP server entry has the wrong
commandorargs. Runlilctx servedirectly from a terminal and check it doesn't error out immediately. (It will sit there waiting for JSON on stdin — that's fine.) - The
envblock in the MCP config is missing the API key, so the process is exiting at startup withenv var ... is unset. - The path to the binary is wrong / not on
PATH. Use an absolute path. - You added the entry but didn't restart Claude Code.
Check Claude Code's MCP logs — failures during server spawn show up there.
init deliberately refuses to overwrite. Delete the file first (or pass
--path to write somewhere else).
Right — the vector column type is fixed at table-creation time. There is
no migration path. Delete data_dir, then lilctx index again. Yes, this
re-bills your embeddings provider for the whole corpus.
You added a println! somewhere reachable from serve. That breaks the
MCP protocol. Replace it with eprintln! or tracing::info!. The
print_stdout = "deny" clippy lint is supposed to catch this — if it
didn't, something is #[allow]ing it.