Troubleshooting

Desktop app & local data

Fix desktop and self-hosted startup problems — the database lock, "can't reach the server", a stuck update — and find where your local data lives and how to recover it.

This page is for people who run Alaf Server on their own machine — the desktop app, or a self-hosted install that uses the built-in database. If you're on Alaf Server Cloud, none of this applies; we run the database for you.

One folder, one process

When you don't point Alaf Server at a real Postgres, it uses PGlite — an embedded Postgres that keeps everything in a single folder on disk. Only one Alaf Server process may use that folder at a time. Most of the problems below come from two processes trying to share it, or from that folder getting into a bad state. If you run your own Postgres (the Docker Compose setup), the lock issues here don't apply to you.

"Another Alaf Server instance is already using the database"

Symptom / what you see

Alaf Server won't start. Self-hosted or running from source, the process exits on launch and your terminal (or log) shows a message like:

Another Alaf Server instance is already using the database at /…/data (pid 12345). PGlite allows only one process per data directory; opening a second would corrupt it. Stop the other instance (e.g. quit the desktop app) and retry. If you are certain no Alaf Server process is running, remove: /…/data.lock

On the desktop app you instead get a native dialog titled “Alaf Server failed to start” whose body reads “Local services failed to start after 3 attempts.” — the message above is the underlying cause, printed to the app's console logs prefixed [api].

What it means (plain words): the database folder can only be opened by one program at once, and something is already holding it. Usually that "something" is another copy of Alaf Server — a second window of the desktop app, a bun dev you left running, or an older process that didn't shut down yet.

How to fix:

Close the other one

Quit any other Alaf Server you have open — a second desktop window, a terminal running alaf server or bun dev, or a leftover process from an update. Then reopen the app.

Give it a moment, then retry

If Alaf Server crashed last time (rather than quitting cleanly), the lock heals itself on the next start once it sees the old process is gone. It also waits a few seconds for a clean hand-off during restarts. Wait a moment and launch again.

Only if you're certain nothing is running — remove the lock

The message ends with the exact path of a lock file, named <data-dir>.lock (a sibling of your data folder). If you're sure no Alaf Server process is alive, delete that one file and start again. It's safe to remove — it never contains your data. Do not delete anything inside the data folder itself.

“…locked by a process on a different host”

A different wording — "The Alaf Server database … is locked by a process on a different host … PGlite data directories cannot be shared across machines" — means your data folder is on a network/shared drive that another machine opened. PGlite folders can't be shared across computers. Move the data to local disk (or set PGLITE_DATA_DIR to a local path), and remove the lock file it names only if that other host is truly done with it.

"Cannot reach the server" / "fetch failed" on start

Symptom / what you see

The window opens but stays blank or throws a red toast reading “Cannot reach the server. Make sure the API is running.” In logs you may see the raw Node message fetch failed. Sometimes instead you get the “Alaf Server failed to start” dialog saying "Local services failed to start after 3 attempts."

What it means (plain words): the desktop app runs two things for you behind the scenes — the API and the dashboard — each on its own port picked at launch. This message means the dashboard came up but the API isn't answering yet. Most often it's simply still booting; occasionally the API crashed on startup, and the most common reason it crashes is the database lock from the section above.

How to fix:

  1. Wait a few seconds. On the first launch after an install or update the API has to run database migrations before it answers. The app polls for it — give it up to a minute.
  2. Check it isn't really the lock error. If you also see "already using the database," fix [that](#another-alaf server-instance-is-already-using-the-database) first — a locked-out API never comes up, which is what leaves the dashboard unable to reach it.
  3. Fully quit and reopen. Quit the app completely (not just closing the window), confirm no alaf server process is left running, then start it again. It picks fresh ports automatically, so a busy port won't block it.

Where the details are

The desktop app prints both servers' logs to its console, prefixed [api] and [dashboard]. If it keeps failing, that output tells you which one died and why — include it if you file an issue.

A stuck or failed update

Symptom / what you see

The update download bar sits frozen, or you pressed Update now, the app quit, and it never came back — or it reopened straight into “Alaf Server failed to start.”

What it means (plain words): the desktop app checks for updates by pulling the latest public GitHub release — it only ever pulls, nothing is pushed to you. It downloads the installer, then a small background script waits for the app to fully exit, swaps in the new version, and relaunches it. Two things commonly interrupt that: the download can't reach GitHub (offline, rate-limited, slow link), or the new copy tries to open the database before the old one has finished letting go of it.

How to fix:

  1. If the download is frozen: check your internet connection. A failed or offline check just resolves to "no update," so a stuck bar usually means a slow or blocked connection to GitHub. Close the update prompt and try again later.
  2. If it quit and didn't reopen, or reopened on an error: wait a few seconds (the old version needs a moment to release the database), then start Alaf Server yourself. If it shows the lock error, follow [the fix above](#another-alaf server-instance-is-already-using-the-database).
  3. Install it by hand: download the installer for your platform from the project's GitHub Releases page and run it over your existing install. Your data folder is untouched by reinstalling.

It falls back to a manual installer

If the seamless self-replace can't complete, Alaf Server doesn't leave you stranded — it opens the downloaded installer and quits so you can finish the update yourself. Automatic updates are off by default; the toggle lives under Settings → Instance → Updates. See the Updating guide for the full flow.

Where your local data lives

Everything Alaf Server stores locally sits in one place per install. Quit Alaf Server before touching any of it.

InstallData folder
Desktop app — macOS~/Library/Application Support/Alaf Server/data
Desktop app — Windows%APPDATA%\Alaf Server\data
Desktop app — Linux~/.config/Alaf Server/data
Self-hosted / CLI (default)~/.alaf server/data
Self-hosted with an overridewhatever you set in PGLITE_DATA_DIR

A few companion files live beside the data:

  • <data-dir>.lock — the single-instance lock (a sibling of the data folder, never inside it). Safe to delete only when no Alaf Server is running.
  • On the desktop app, its parent folder also holds config.json (your app settings), ports.json (the ports it reuses so you stay logged in across restarts), and auth-secret (keeps your session valid). Leave these unless you're deliberately resetting.

Set your own data path (self-hosted)

Point the self-hosted API at any folder with the PGLITE_DATA_DIR environment variable — recommended if the default ~/.alaf server/data isn't where you want your data to live. A leading ~ is expanded for you.

Recovering a corrupted database

Symptom / what you see

Alaf Server won't start and the logs show RuntimeError: Aborted(), often alongside DrizzleQueryError: Failed query: CREATE SCHEMA IF NOT EXISTS "drizzle".

What it means: the embedded database folder was damaged — most often by a hard kill mid-write, or by two processes opening it at once (exactly what the lock exists to prevent). It's a data-folder problem, not a bug in your project.

How to fix (running from source / a self-hosted checkout): two recovery scripts live in the repo and back up your data before changing anything:

# First try: backs up the folder, clears a stale lock, trims the corrupt WAL tail
bun --cwd packages/db db:heal-pglite

# Deeper recovery if that isn't enough (needs a local Postgres 17 for pg_resetwal)
bun --cwd packages/db db:heal-pglite-resetwal

Both copy your data aside first (to <data-dir>.backup-… / .preheal-…), so you can always fall back to the original if recovery isn't what you wanted.

Desktop app, last resort

If you're on the packaged desktop app (no repo checkout) and it won't recover, quit Alaf Server, copy your data folder somewhere safe, then move the original aside. Alaf Server recreates a fresh, empty database on the next launch. This gets you running again but starts you over locally — your backed-up copy is your only route back to the old data, so keep it.

Still stuck?

On this page