RE-call Setup

When something breaks

The errors this install produces, and what each one means.


Find the message you are looking at, not the step you are on. Each entry shows the symptom first, says in plain language what it means, and ends with the command or the action that clears it.

01

Python and Docker

Everything else depends on these two answering. If the very first check in the guide gave you nothing back, start here.

The shell says it does not know what python is

Error
python : The term 'python' is not recognized as the name of a cmdlet, function, script file, or operable program.
At line:1 char:1
or, on macOS and Linux:
command not found: python

Two different things produce this. Either Python is not installed, or it is installed and the shell was never told where to find it. On Windows the installer only puts Python on your PATH when you tick the box during installation, and there is a second launcher called py that often works when python does not. On macOS and Linux the command is python3, and plain python may not exist at all.

Find out which case you are in.

py --version

If that prints a version, Python is on the machine and only the name was wrong. On macOS and Linux, use python3 everywhere this guide writes it and you are done. On Windows you can keep typing py, but I recommend reinstalling from python.org with the Add python.exe to PATH box ticked, because the rest of the guide, and every tool that shells out to Python, expects the plain name to work.

The version is below 3.11

Error
Python 3.9.13

Not an error message, but it stops you all the same. RE-call's floor is 3.11, and 3.12 to 3.14 are supported. An older interpreter will fail somewhere during the install with a syntax or dependency error that does not name the real cause.

Install a current version from python.org and check again before continuing. You do not have to remove the old one.

On Windows: Python works, but indexing a folder finds nothing

The Microsoft Store build is the usual cause

Python installed from the Microsoft Store runs inside a sandbox that rewrites file paths. Commands run, versions print, and then index reads a folder that is not the folder you meant. Install from python.org instead.

You can confirm which build you have. A path containing WindowsApps is the Store build.

python -c "import sys; print(sys.executable)"

docker is not recognised, or the daemon will not answer

Error
docker : The term 'docker' is not recognized as the name of a cmdlet, function, script file, or operable program.
or
Cannot connect to the Docker daemon. Is the docker daemon running?

The first message means Docker Desktop is not installed, or its command line tool was never added to your PATH. The second is the more common one, and it means something quite specific: the docker command exists and ran, but the engine behind it is not up. Installing Docker Desktop does not start it.

Open Docker Desktop from your applications and wait until it reports that the engine is running. Then check from the terminal.

docker ps

An empty table with column headings is a success. It means the engine answered and has nothing running yet.

02

Database problems

Everything in step 1 of the install guide, and every later error that says the word "refused".

Port 5432 is already allocated

Error
docker: Error response from daemon: driver failed programming external
connectivity on endpoint recall-db:
Bind for 0.0.0.0:5432 failed: port is already allocated

Something else on your machine is already listening on 5432, and it is almost always another PostgreSQL: one you installed years ago, one a different project started, or a second copy of this container. Docker will not put two things on one port.

You have two ways out. Stop whatever is holding the port, or leave it alone and give RE-call a different door into the same container.

docker run -d --name recall-db -e POSTGRES_USER=recall -e POSTGRES_PASSWORD=recall -e POSTGRES_DB=recall -p 5433:5432 pgvector/pgvector:pg18

If you take the second route, one thing changes everywhere

Every connection string in the rest of the guide becomes postgresql://recall:recall@localhost:5433/recall, including the one inside .mcp.json. The 5433:5432 means "reach the container's 5432 by knocking on 5433 here", so only the number you type changes.

The container name is already in use

Error
docker: Error response from daemon:
Conflict. The container name "/recall-db" is already in use
You have to remove (or rename) that container to be able to reuse that name.

An earlier attempt created a container called recall-db. It may be stopped, it may be broken, but the name is taken. Remove it and run the command again.

docker rm -f recall-db

If the old container was working and only the name collided, check first whether you simply want to start it again rather than throw it away. The next entry covers that.

Connection refused

Error
connection to server at "localhost" (::1), port 5432 failed: Connection refused
  Is the server running on that host and accepting TCP/IP connections?

Nothing is listening. The database is not running, which after a reboot is the ordinary state of affairs: a stopped container stays stopped until you start it. This is the error behind most failures in schema, index and search, so if you see it there, you are in the right section.

docker ps lists what is running. docker ps -a also lists what has stopped, which is where a container you made yesterday will be hiding.

docker ps -adocker start recall-db

You should see

Output
CONTAINER ID   IMAGE                    STATUS         PORTS                    NAMES
a1b2c3d4e5f6   pgvector/pgvector:pg18   Up 2 seconds   0.0.0.0:5432->5432/tcp   recall-db

If docker ps -a lists no container at all, there is nothing to start. Go back to step 1 of the install guide and run the docker run command.

Your memory disappeared between sessions

Searches that worked before now return nothing, or schema status reports that nothing is installed, and you know you indexed those files. What happened is that the container was removed and recreated. Its data lived inside it, so removing it removed your rows too.

Recreate the container with a named volume, so the data lives outside the container and survives being rebuilt.

docker run -d --name recall-db -e POSTGRES_USER=recall -e POSTGRES_PASSWORD=recall -e POSTGRES_DB=recall -p 5432:5432 -v recall_pgdata:/var/lib/postgresql pgvector/pgvector:pg18

The data already lost is gone, so apply the schema and index your memory once more. From then on, rebuilding the container costs you nothing.

03

Install problems

Getting the package onto your machine, and getting the right one.

The install succeeded but the import fails

Error
Traceback (most recent call last):
ModuleNotFoundError: No module named 'recall.cli'

You installed recall rather than recall-rag. The name recall on PyPI belongs to an unrelated project, and it happens to occupy the same import name, so having both in one environment leaves Python finding the wrong one.

The package is recall-rag, the command is recall

You install recall-rag. In code and on the command line it is spelled recall. That asymmetry is the single most common install mistake.

python -m pip uninstall recallpython -m pip install "recall-rag[fastembed]"

pip is not recognised

Error
pip : The term 'pip' is not recognized as the name of a cmdlet, function, script file, or operable program.
or
command not found: pip

pip lives inside Python as a module. A standalone pip command is a convenience shim that is not always installed, and when several Pythons share a machine it is not always the shim for the interpreter you mean. Calling it through Python removes the guesswork, because the pip you reach is by definition the pip belonging to the Python you named.

That is why every install line in this guide is written python -m pip rather than pip. Use that form and this error cannot occur.

Permission denied while installing

Error
ERROR: Could not install packages due to an OSError: [Errno 13] Permission denied
Consider using the `--user` option or check the permissions.

You are installing into a Python that the operating system owns, and it is protecting itself. Running the install as an administrator would work and I do not recommend it: it mixes your project's dependencies into the interpreter your system relies on, and uninstalling later gets messy.

Create a virtual environment instead. It is a private copy of Python inside a folder, and it needs no special permissions.

python -m venv .venv.venv\Scripts\Activate.ps1python -m pip install "recall-rag[fastembed]"

You have to activate it in every new terminal

The activation line is the second one above. Open a fresh terminal and RE-call will look missing again until you run it. If a command that worked an hour ago suddenly reports that the module is not found, this is usually why.

Results are meaningless, or the wizard offers you nothing

If you installed plain recall-rag without the square brackets, you installed no embedding model at all. What you have instead is a placeholder that turns text into vectors by hashing it, which is useful for checking that the plumbing runs and useless for finding anything by meaning. The wizard will notice, and it will fall back to that placeholder rather than offering you a real choice.

The extra is what supplies the local model. Re-run the install with it.

python -m pip install "recall-rag[fastembed]"

The first index sits there doing nothing

This one is not a fault

The first time you index anything, the local model has to be downloaded, roughly 130 MB. It happens once, during a command that otherwise finishes in a second, so it reads as a hang. Give it a few minutes on a normal connection. Every index after that starts immediately.

04

Schema problems

Creating the tables, and keeping their shape agreeing with your embedding model.

Connection refused during schema apply

The command never reached a database. This is not a schema fault at all, and applying it again will not help. Your container is not running: go to database problems, get docker ps showing recall-db, then run the schema apply line again unchanged.

vector type not found in the database

Error
psycopg.ProgrammingError: vector type not found in the database

The wizard normally prepares the database for you, so this means it never got the chance: either it could not reach the database when you ran it, or this database was created outside the guide. It is running and reachable, but nothing has ever set it up: the vector extension that stores and compares embeddings is not installed, so the very first query that mentions a vector column fails. It usually appears from index or search, not from the step that was actually missed, which is what makes it confusing.

You do not need to install the extension by hand. Applying the schema does it for you, as the first thing it does. Re-running setup against a reachable database will also do it.

python -m recall.cli --migration-dsn postgresql://recall:recall@localhost:5432/recall schema --dim 384 apply

SchemaTooOld

Error
recall.schema.SchemaTooOld: table 'chunks' needs schema migration(s)
['0001', '0002', ...]; run `recall schema apply`

Almost always this simply means the schema has never been applied to this database, and the wizard did not do it for you because it could not reach the database at the time. Apply it and the message goes away.

There is a second, rarer form of it, which names global generation migrations instead. RE-call's migrations are global: they set up the extension, the shared machinery, and the default chunks table that everything else is layered on. Until those have run once, the database has no foundation to build a custom table on, and any command that expects one refuses.

Never start with a custom table on a fresh database

Apply the global migrations against the default chunks table first, which is what the wizard does for you. Custom tables are an addition to a migrated database, not a substitute for migrating it.

python -m recall.cli --migration-dsn postgresql://recall:recall@localhost:5432/recall schema --dim 384 applypython -m recall.cli schema status

The table and the embedder disagree about width

An embedding model turns a piece of text into a list of numbers, and every model produces a list of one fixed length. The table's vector column is created at one specific width, and it will accept nothing else. If the two do not match, nothing can be written and nothing can be searched.

The local fastembed default produces 384 numbers, which is why the install guide builds the table with --dim 384. Here is what the others produce.

EmbedderVector widthNote
fastembed, default384What the install guide uses. Runs locally.
fastembed, base768Larger local model, larger download.
fastembed, large1024Larger still.
voyage1024Cloud embedder. Your text leaves the machine.
openai1536Cloud embedder. Your text leaves the machine.
hashing64Placeholder. No meaning, useful only for testing plumbing.

Changing embedder therefore means rebuilding the table at the new width. There is no conversion: the numbers a different model produces are not a translation of the old ones, so the old rows have to be indexed again.

Why RE-call refuses rather than padding the vectors to fit

A vector is only meaningful against other vectors from the same model. Two lists of 384 numbers from different models are not comparable, and padding a 384 wide vector out to 768 would produce something a database will happily store and index, and that will return confident nonsense forever afterwards.

Refusing at the point of the mismatch is the cheap failure. The alternative is a corpus that looks healthy, answers every question, and is wrong in a way no error message will ever tell you about.

05

Setup wizard problems

The wizard asks its questions, checks your answers against the database, and refuses to write a configuration it knows will not work. Most of what looks like it going wrong is that check firing.

It keeps re-asking the embedder question

You choose an embedder, and instead of moving on the wizard asks again. It is not stuck. The embedder you picked produces vectors of one width, the table you built has another, and rather than writing a .env that fails on your first index it puts the question back to you along with the exact command that would reconcile the two. The message has this shape.

Error
table 'chunks' uses vector(384), requested dimension is 768
fastembed base produces 768-dimension vectors. Either create a table with
`recall schema --dim 768 apply`, or pick an embedder matching the table you have.

Both answers are legitimate, and which one is right depends on what you want.

  • Keep the table. Choose the embedder whose width matches it. On a first install that is fastembed at 384, and it is the answer the install guide expects.
  • Keep the embedder. Leave the wizard and rebuild the table at the new width, then start setup again. Note that the command the wizard prints is abbreviated: schema apply performs DDL, so it needs --migration-dsn added, exactly as the schema section shows. Anything already indexed has to be indexed again afterwards.

It exits saying no embedder matches this table

The same check, with nothing left to offer. Every embedder available in your environment produces a width the table cannot hold, so there is no answer you could give that would work, and the wizard stops rather than looping forever.

Two ways forward. Install the extra that provides an embedder of the right width, most often [fastembed] for a 384 wide table. Or rebuild the table at a width one of your installed embedders uses, with the schema --dim <n> apply command and the table in schema problems.

It picks the hashing placeholder by itself

This means the fastembed extra is missing

The wizard auto selects hashing only when nothing else can run. It is a placeholder that turns text into vectors without understanding any of it, so search will match on nothing you would recognise as meaning. Install "recall-rag[fastembed]" and run setup again.

Every database command refuses, and your .env looks odd

A .env file can be damaged, most often by a write that was interrupted partway and left a NUL byte in the middle of it. RE-call will not read a configuration it cannot trust, so every command that touches the database stops, which looks like a database fault and is not one.

There is an escape hatch, and setup is deliberately exempt from the guard so that you can always run it to write a clean file. Repairing is the better fix.

python -m recall.cli setup

If you need another command to run before you have repaired the file, override the guard for that one invocation.

$env:RECALL_IGNORE_BROKEN_DOTENV = "1"python -m recall.cli schema status

It refuses the connection string as insecure

The credential this guide uses is recall:recall, which is a published username and password. That is fine against localhost, where nothing outside your machine can reach the port. Point the same credential at a host that is not local and RE-call refuses, because a database on the network with a password anyone can read in a setup guide is not a database, it is an open door.

The right fix is a real credential on the server, and the guard then stays out of your way. For setup specifically, pass the connection string on the command line.

python -m recall.cli --dsn postgresql://myuser:mypassword@db.example.com:5432/recall setup
The override exists, and I would not reach for it first

RECALL_ALLOW_INSECURE_DSN=1 switches the guard off. It is there for the cases where you genuinely know better, such as a throwaway container on a private network during a test.

Reaching for it on a real deployment converts a loud refusal into a silent risk, and the refusal is cheaper to fix now than the exposure is to discover later. Change the password instead.

06

Indexing and search

Getting your files into the database, and getting sensible answers back out. The first entry here is the one people hit most.

search ends in a Python traceback

Error
Traceback (most recent call last):
  ...
recall.trust_policy.TrustRefusal: INDEX_NOT_READY: refused in strict trust mode (tenant='default', generation=None, calibration_status='missing')

This is the most common failure in the whole install

Strict mode is the default, and in strict mode RE-call will not answer from a corpus whose confidence threshold has never been measured. It raises rather than quietly degrading, because a threshold nobody measured is not a threshold, and answering anyway would be exactly the behaviour the product exists to prevent. You have not measured one yet, so the very first search stops here.

The fix is the line from step 5 of the install guide. It says "I know this threshold is a placeholder, show me the results anyway", and everything you get back is stamped as uncertified so you cannot forget.

Add-Content .env "RECALL_TRUST_MODE=development"

That gets you moving today. The real answer is to measure a threshold on your own corpus, which replaces the placeholder with a number that means something and lets you drop development mode entirely. That is the calibration page, and it is worth doing once your memory holds material you care about being right.

If you added the line and the traceback persists, check you are running the command in the same folder as the .env file. The setting is read from the working directory.

Every result is flagged DEGRADED

Output
[development] using an UNCERTIFIED demonstration threshold of 0.5. This is not a
calibration: it is bound to no tenant, generation or corpus, and production
refuses rather than assuming it.
[DEGRADED:INDEX_NOT_READY] query='how many requests per minute can a client make?'

Not an error. It is the label doing its job.

In development mode the threshold in use is an uncertified demonstration value, bound to no corpus and no model. The flag is RE-call telling you so on every single result, so that nothing downstream can present these answers as measured ones. It disappears when you calibrate, and not before.

Nothing was indexed

Output
indexed 0 chunks from 0 files

The folder was found and read, and nothing in it matched. The default pattern is **/*.md, so a directory of .txt notes, .py source or .rst documents is skipped in silence: from index's point of view the folder is empty of things it was asked for.

Say what you want with --glob.

python -m recall.cli index notes/ --glob "**/*.txt"

A re-index stops, saying it would remove most of your corpus

When you index a folder again, RE-call removes rows whose source files have gone. If a run is about to delete a large share of what is there, it stops instead. The usual cause is not a deletion at all: you pointed the command at the wrong folder, or a drive was not mounted, or you ran it from a different working directory, and the files look missing because the command cannot see them.

Check the path first. If the files really are gone and you meant it, the override is deliberate and explicit.

python -m recall.cli index memory/ --allow-prune

Indexing refuses under RECALL_ENV=production

Intended, not broken. In production RE-call does not build an index from whatever happens to be on a disk at the moment a command runs. It builds from an immutable manifest, so that what is being served is a thing somebody chose and can point to afterwards. Indexing a live folder would make the corpus depend on the state of a filesystem nobody recorded.

On your own machine, leave RECALL_ENV unset or set to development. If you meant to be in production, build the manifest rather than turning the guard off.

Searches run, but the answers are not useful

No error, no abstention, just results that are technically related and practically useless. This is almost never a configuration problem. It is what happens when the memory files are too broad: a long document covering six subjects produces chunks that are a bit about all of them and precisely about none, so nothing scores clearly against a specific question.

The fix is editorial rather than technical. One file, one subject, stated plainly, with the specifics in it. Your memory covers what makes a file findable and what to keep out of the corpus.

07

Claude Code problems

The MCP server is a separate process with its own configuration. Most problems here come from assuming it shares something with your terminal that it does not.

The server does not appear in Claude at all

You run /mcp, and there is no recall server listed. Three things to check, in this order.

  • The [mcp] extra is installed. The server component is not part of the base install. Run the install again with "recall-rag[fastembed,mcp]".
  • .mcp.json is in the folder Claude Code was started from. Not your home directory, not the folder above. Claude reads it from the working directory it was launched in, so a file in the right project and the wrong folder is invisible.
  • Claude Code has been restarted. The file is read when the session starts. Editing it while Claude is running changes nothing until you quit and start again.

The server command fails to start

Error
No module named recall_mcp.__main__; 'recall_mcp' is a package and cannot be directly executed

The module name in .mcp.json is one word short. recall_mcp is the package; the server inside it is recall_mcp.server, and that is what has to be run.

.mcp.json
"args": ["-m", "recall_mcp.server"]

The server starts, but every search abstains or errors

The MCP server does not read your .env

Your terminal picks up .env from the working directory. The server is launched by Claude, not by your shell, and it does not read that file. Any setting you rely on has to be repeated inside the env block of .mcp.json, including the connection string and the trust mode. A missing RECALL_TRUST_MODE there is the usual reason searches work in the terminal and fail in Claude.

.mcp.json
{
  "mcpServers": {
    "recall": {
      "command": "python",
      "args": ["-m", "recall_mcp.server"],
      "env": {
        "RECALL_SERVING_DSN": "postgresql://recall:recall@localhost:5432/recall",
        "RECALL_TENANT": "default",
        "RECALL_TRUST_MODE": "development"
      }
    }
  }
}

On macOS and Linux, the command name is wrong

The example above says "command": "python", which is the Windows spelling. On macOS and Linux change it to "python3", the same name you type in your own terminal. A wrong command name here shows up as a server that fails to start with no obvious explanation, because the failure happens inside Claude rather than in front of you.

Claude Desktop ignores your edit

Claude Desktop reads claude_desktop_config.json when it launches. Closing the window is not enough on either platform, because the application keeps running. Quit it fully and open it again, then check that the server is listed before you conclude the configuration is wrong.

Claude cannot see rows you indexed yourself

The table is fixed. The tenant is not.

The server always uses table chunks, and there is no setting that points it at another one. The tenant is different: it reads RECALL_TENANT from the env block of your configuration and falls back to default only when you have not set it.

So there are two distinct causes, with two different fixes.

  • You indexed under another tenant, for example with --tenant work. Do not re-index. Add "RECALL_TENANT": "work" to the env block in .mcp.json and restart Claude, and the existing rows become visible.
  • You indexed into a custom table, with --table. Here re-indexing is the only route, because the server cannot be pointed at a different table. Index the material again without --table so it lands in chunks.

If your problem is not on this page

Open an issue. Include the exact command you ran, the full message you got back, your operating system, and the output of python -m recall.cli schema status. Those four things are usually enough to identify the cause without a conversation.

github.com/GiulioDER/RE-call/issues