<like this> stands for something specific to your machine.
Upsolve’s messages write commands as upsolve-analytics <command>. Run them as npx @upsolve-labs/analytics <command>.
Before Upsolve starts: the installer
These come fromnpx @upsolve-labs/analytics itself, before anything is downloaded or run.
Node.js is too old
brew install node@24, or the installer from nodejs.org), open a new terminal and check node --version. Node.js 23 is not covered.
Not a supported Mac
It does not know where to download from
npx @upsolve-labs/analytics@latest. If you host the downloads yourself, set UPSOLVE_DOWNLOAD_BASE_URL. The checksum still comes from the npm package, so a mirror cannot swap the file.
https:// address. Plain http:// is accepted only for localhost, 127.0.0.1 and [::1].
The download fails
The installer retries a failed download twice (three tries in all), pausing between them.~/.upsolve/versions. The disk is usually full, or that folder is not writable by you. Free some space or fix the permissions, then run the command again.
npx @upsolve-labs/analytics@latest.
The checksum does not match
The archive will not unpack
/usr/bin/tar. tar failed usually means the disk is full or ~/.upsolve is not writable; free some space and run the command again. The last four mean the download passed its checksum but is not a usable release. Nothing is installed in that case, so it is safe to run the command again; if it repeats, contact support.
It does not have that release
--version picks which release the installer runs. Give it a number such as 6.24.101. (A bare --version or -v prints the installer’s own version.)
The installer’s own files are damaged
npx @upsolve-labs/analytics@latest, which fetches a fresh copy.
An unexpected error
Finding and using PostgreSQL
Upsolve looks for PostgreSQL in this order, and takes the first it finds without trying the next:--database-url; the database it used last time (kept in ~/.upsolve/config.json); DATABASE_URL, else the PG* variables (PGHOST, PGUSER and so on); and finally <your macOS user>@localhost:5432. From a server it always uses a database called upsolve.
No PostgreSQL is running
psql postgres -c "select version()". If you use Homebrew, brew services list shows whether it is running.
--database-url. Upsolve remembers the new one.
Wrong role, password or TLS setting
@ becomes %40, for example). The password is stored in ~/.upsolve/config.json, which only you can read.
The URL is not valid
<where it came from> is --database-url, databaseUrl in config.json, DATABASE_URL or The PG* environment variables. Fix that value.
PostgreSQL is too old
The database is not Upsolve’s, or the role cannot use it
--database-url.
The database Upsolve used has gone
upsolve database, restore it with psql into the database the message names. To start fresh, pass --database-url.
Starting Upsolve
Upsolve is already running
npx @upsolve-labs/analytics stop. It also cleans up processes a crashed run left behind. status shows what it sees.
A port is in use
--port is used exactly as given, or not at all. The address Upsolve opens is always printed as Upsolve Local is running at <address>.
The database could not be migrated
Another migration run is in progress; waiting for it to finish.).
If the reason mentions an extension:
--database-url postgres://postgres@localhost:5432/upsolve), or install the server’s contrib extensions.
The database is newer than this Upsolve
npx @upsolve-labs/analytics@latest. To go back to the older release on purpose, restore the backup taken before the upgrade first (npx @upsolve-labs/analytics restore latest, see Restoring a backup), then run that release.
The backup before an upgrade failed
pg_dump into ~/.upsolve/backups. When that copy fails, it does not upgrade. The lines after the message are pg_dump’s own explanation: usually a pg_dump older than the server (install the client tools that match your PostgreSQL, for example brew install libpq), or a role that cannot read every table. Fix that and start again, or start once with --no-backup if you do not need the copy.
Upsolve could not check the database
migrations table. Nothing was changed; fix the cause and start again.
It starts and then does not become healthy
api is the app, dashstra is the agent) and prints the end of its log. The reason is almost always in those lines: a port that something else grabbed, a database that stopped, or a setting that is wrong. Upsolve restarts a part that crashes, and gives up on a start after three restarts. A slow Mac can need longer than the default five minutes: --start-timeout 600. Read npx @upsolve-labs/analytics logs supervisor too.
The release is incomplete
~/.upsolve/versions/<release>. Delete that release directory and run npx @upsolve-labs/analytics again to download it afresh.
Messages for people running from a checkout
These appear only if you run Upsolve from a source checkout (start --from-repo) rather than through npx.
Using the app
The page says Forbidden
http://127.0.0.1:<port> or http://localhost:<port> (the port is printed when it starts). Opening it by another name, through a tunnel or a proxy, or from another computer is refused on purpose: with no login, that check is what keeps other websites and other machines out.
The agent does not answer, or says no AI provider is configured
ANTHROPIC_API_KEY, OPENAI_API_KEY, LLM_PROVIDER or OPENROUTER_API_KEY are not read: a key exported in your terminal does not stand in for the one saved in the app, even if it is set when you start Upsolve.
encryptionKey in ~/.upsolve/config.json. This happens when the database came from another install, or config.json was replaced. Enter the key again in the AI provider settings.
npx @upsolve-labs/analytics logs dashstra for the full text.
Upgrading to Upsolve Cloud says the cloud does not support it yet
UPSOLVE_CLOUD_URL (the cloud’s web address) and UPSOLVE_CLOUD_API_URL (its API address) set; if you set those yourself, check that they are the cloud you meant.
The message goes on to say that the sign-in key Upsolve Local created is listed in Account settings in Upsolve Cloud. A cloud this old cannot yet be asked to delete it, so Upsolve Local keeps trying and removes it as soon as the cloud can. You can delete it yourself in Account settings at any time.
The database refuses the connection
When you press Test & Create Connection, Upsolve connects to your database from your own Mac and shows what the database answered. The reason is in the message:localhost:5432 is filled in for you; a server started by another tool is often on a different port).
Commands
Configuration
jwtTokenSecret, encryptionKey and filesKey are generated once and cannot be read or changed through the command. Changing the encryption key would make every stored credential unreadable.
A damaged config.json
config.json holds the key that decrypts what Upsolve stores. Do not delete it to make the error go away: Upsolve would make a new key and could no longer read your connections’ passwords. Open the file in an editor and fix the line the message names, or put back a copy from a backup. Only if this install holds nothing you need can you delete ~/.upsolve/config.json and start over.
A misspelled or unknown option
Every command prints the problem followed by its own usage text (the same text as<command> --help), and exits with status 2. For example, npx @upsolve-labs/analytics start --prot 4500 prints Unknown option '--prot' and the options of start.
Logs, stop and status
status prints NOT RESPONDING for a part that is running but not answering, and exits with status 3 when Upsolve is not running (0 when it is), so a script can use it. stop waits up to 60 seconds for requests in flight (change it with --timeout), then kills what is left, and says It did not exit in time and was killed. when it had to. A second Ctrl-C in the terminal Upsolve runs in also means stop now.
Could not claim <path> means Upsolve could not take its instance lock (~/.upsolve/run/supervisor.pid) after three tries, which happens when two starts race right after a crash. Run npx @upsolve-labs/analytics stop, then start again.
Restoring a backup
npx @upsolve-labs/analytics restore <backup> loads a backup into a new database and points Upsolve at it; the database you were using is not touched. Name a file from ~/.upsolve/backups, a path to a .sql file, or latest. A backup exists only once an upgrade has taken one, which also needs pg_dump. A restore needs psql, needs Upsolve stopped (npx @upsolve-labs/analytics stop), and needs an empty database: leave out --database-url and Upsolve creates one for you. When the restore itself fails, the new database is removed again and nothing changes. A file that is valid SQL but not an Upsolve backup is the exception for a database you named with --database-url: it ran, so its contents stay in that database, and you need to empty it before restoring into it again. The encryption keys are not in a backup, so keep ~/.upsolve/config.json.