Quick Start
Read the startup pill
starting engine, then engine :PORT on success or engine failed with a tail on failure.Open the engine log
Reset the engine if it's stuck
Startup States
Startup Log (Breadcrumb)
Every launch writes one line to a small log file in the OS temp directory before the window is built, so a launch is always traceable even when no window appears.Where the file lives
%APPDATA%\PraisonAI is created, so the log is available even on a first launch where the data directory has not yet been created. Creation and provisioning are distinct moments now: the breadcrumb is written in main(), before setup() creates the folder, so the temp log is always the earlier signal.
Line format
Each launch appends one tab-separated line:secondary first (before the process knows it is first), then primary:
Reading the log to diagnose a silent launch
Open the file and read the latest line for the launch you just started. A launch that was handed off to an existing primary writes only its ownsecondary line and exits with code 0 — that is expected behaviour, not a crash.
The data folder is a second signal alongside the log line. It is created as soon as the primary reaches setup(), so a primary line with no data folder points at a permissions or disk problem on the folder’s parent — the app prints [praisonai] could not create <path>: <error> to stderr and keeps going. A missing folder after a secondary-only launch is normal: a handed-off launch creates nothing.
Common Failures
The Default model picker suggested ids the app cannot run (pre-4756)
The Default model picker suggested ids the app cannot run (pre-4756)
claude-sonnet-4-20250514, claude-opus-4-20250514, gemini-2.0-flash, and ollama/llama3.2.- Bare Anthropic/Google ids without a Base URL take the OpenAI path and are sent to
api.openai.comcarrying your OpenAI key, so they fail with an OpenAI error that namesplatform.openai.com. ollama/llama3.2is a slashed id, and since PraisonAI#4722 the shipped desktop venv refuses slashed ids (nolitellm).
base_url) to the provider’s OpenAI-compatible endpoint and type its bare model id in the combobox. Both fields are Requires restart. See Models & API Keys → Using another provider.Setup wizard was invisible behind a restored Train view on first run (pre-4471)
Setup wizard was invisible behind a restored Train view on first run (pre-4471)
setup needed or engine failed, the setup wizard and the failure banner rendered into #thread — which the Train view had already hidden behind body.training #thread { display: none }. The title bar read setup needed, the Train form filled the screen, and there was no visible way to start setup. This was the reported Windows dead end in PraisonAI #4441.Fixed in PraisonAI #4471. showView(name, {persist=true}={}) grew a persist option; a new showEngineGate() calls showView('chat', {persist: false}); boot() runs the gate before both the setup-needed and failed branches. The forced Chat switch is not persisted, so the user’s deliberate Train choice returns once the engine is up. If you saw the wizard vanish behind Train after upgrading or on a clean install, upgrade to this release.A follow-up in PraisonAI #4623 closes the last rough edge: the temporary Chat switch is no longer stuck on the screen until the app is relaunched. boot() now calls a restoreView() helper right after the engine finishes provisioning, which re-reads localStorage.getItem('view') and re-applies it — so the moment you click Get started and setup succeeds, your saved Train view returns in the same session.The app opened but the data folder does not exist
The app opened but the data folder does not exist
primary line with no data folder points at a permissions or disk problem on the folder’s parent (the app prints [praisonai] could not create <path>: <error> to stderr and keeps going, so the window still opens). Only a secondary line means this launch handed off to an already-running app, which does not create anything.Right-click or an error dialog doesn't appear (older builds)
Right-click or an error dialog doesn't appear (older builds)
window.prompt() returned null and window.alert() did nothing. This made three actions look broken:- Right-click on a conversation → Move to project issued no request.
- Adding an MCP server with a blank name silently did nothing.
- An engine rejection when adding an MCP server showed no error.
The tools ran, but no answer came back
The tools ran, but no answer came back
no_answer. The tools succeeded and their results are shown above the banner, but the model produced no follow-up answer for them.From praisonaiagents 1.7.2 onward the library raises loudly instead of ending the stream silently, so this banner is the only user-visible sign. Retry the turn — the tool result is already in the agent’s history, so the retry often answers in plain text.Requires praisonaiagents>=1.7.2 in the engine venv. From PraisonAI #4670 onward, the desktop app compares the shipped requirement against a stamp inside the venv on every launch and re-runs the install once when they differ — so an install stuck on 1.7.1 is brought to the current floor automatically the next time you open the app (the tray reads Engine: updating… while it runs). If you are on a build before that fix and see "the engine produced no output" on every tool call, upgrade the desktop app: pre-4670 builds froze the venv at whatever the first run installed.engine failed: missing dependency
engine failed: missing dependency
ModuleNotFoundError / ImportError. The startup failure now offers Set up the environment and Copy details buttons and treats an import error as a setup problem rather than an unfixable failure.Click Set up the environment to rebuild the venv. As a fallback, Copy details copies the exact error, and you can reinstall the SDK by hand into the venv the app resolves — the desktop pins a floor of praisonaiagents>=1.7.2:First-run setup was interrupted
First-run setup was interrupted
uv/pip — leaves the venv half-built. On the next launch the startup banner offers two buttons:- Set up the environment — rebuild the venv in place (fetch
uv, install a pinned CPython, reinstallpraisonaiagents). - Copy details — copy the exact error to paste into an issue.
Library fixes never reached an existing install (pre-4670)
Library fixes never reached an existing install (pre-4670)
praisonaiagents after that reached brand-new installs only — raising the floor in one release changed nothing for installs that already existed. A user stuck on praisonaiagents 1.7.1 kept hitting "the engine produced no output" on every tool call while the fix had been on PyPI for days, with no in-app way to correct it. The workaround was deleting the venv by hand.Fixed in PraisonAI #4670 (closes #4668). The app now writes a .praisonai-packages stamp inside the venv and, on every launch, compares it against the current requirement — if they differ, it re-runs the install step once, rewrites the stamp on success, and starts the engine against the up-to-date venv. The tray reads Engine: updating… while it runs; a no-drift launch is not slowed because uv is near-instant when nothing changed. Failure never blocks chat: the engine still starts and the UI reports whatever version is actually installed, and because the stamp is only written on install success, a failed update is retried next launch rather than silently recorded as done. Reconciliation only touches the app’s own venv (<data>/venv) — a PRAISONAI_PYTHON override or a checkout venv is left untouched, its owner manages its packages.Engine started against the wrong Python (pre-4519, PYTHONHOME/PYTHONPATH exported)
Engine started against the wrong Python (pre-4519, PYTHONHOME/PYTHONPATH exported)
PYTHONHOME, PYTHONPATH, or PYTHONSTARTUP — common with conda, distro tooling, or a systemd user session — used to have those variables passed straight through to the engine. That redirected the engine’s stdlib or site-packages away from the venv the shell had just proved. The engine either failed to start with ModuleNotFoundError for something clearly present in .venv/, or worse, started against another environment’s praisonaiagents and behaved inconsistently.Fixed in PraisonAI #4519 (closes #4500). The shell now strips PYTHONHOME, PYTHONPATH, and PYTHONSTARTUP; sets VIRTUAL_ENV to the venv root; and prepends the venv’s bin/Scripts to PATH. Every other variable passes through unchanged.If you saw the engine importing from the wrong environment, upgrade to this release. To point the engine at a local praisonaiagents checkout, use PRAISONAI_AGENTS_SOURCE — see the Environment Variables page.A settings save echoed the API key in cleartext (pre-4680)
A settings save echoed the API key in cleartext (pre-4680)
GET /settings had always masked the api_key as bullets, but POST /settings replied with save_settings()’s merged dict — which starts from load_settings(), and that reads the real secret back out of the OS keychain. So every settings write answered with the credential in cleartext, including a write that only changed theme and never mentioned the key. Combined with Access-Control-Allow-Origin: *, any page open in a browser could read it.Fixed in PraisonAI #4680. A single redacted() helper is now applied at both GET /settings and POST /settings, so every settings response masks each SECRET_KEYS entry as bullets. An empty key still comes back as "" so the UI can tell “set” from “unset”. What is stored is unchanged; only what leaves the process is masked. If you inspected a settings write on an earlier release and saw your key in cleartext, upgrade — and rotate that key.Export silently faked a backup when the engine was unreachable (pre-4518)
Export silently faked a backup when the engine was unreachable (pre-4518)
.json file could look like a valid backup and be treated as one.Fixed in PraisonAI #4518 (closes #4502). runAction now try/catch-es its work and surfaces failures via toast('That did not run: …'). Export also checks if(!r.ok) throw before touching the clipboard, so a failed export can no longer overwrite the clipboard with an incomplete payload.Any Settings action against an unreachable engine now shows a toast prefixed That did not run:. If you relied on Export as a backup path on an earlier release, re-verify any Export you took while the pill read engine failed or starting engine.Engine timed out at startup (non-English Windows / Japanese locale)
Engine timed out at startup (non-English Windows / Japanese locale)
PYTHONUTF8=1 and PYTHONIOENCODING=utf-8 to the engine and reads its output loss-tolerantly, so this is fixed. Setting PYTHONUTF8=1 yourself is redundant — the shell already does it.No tray icon on Linux (Wayland / GNOME)
No tray icon on Linux (Wayland / GNOME)
libayatana-appindicator3-1 (or libappindicator3-1) to get the icon back.A fine-tune died on every relaunch on Windows (pre-4515)
A fine-tune died on every relaunch on Windows (pre-4515)
sys.executable, always backslashed) against the expected path (built with a forward slash), and a byte mismatch escalated to taskkill /T /F. That took the engine and its training subprocess with it on every relaunch, so a fine-tune could never survive closing the window.Fixed in PraisonAI #4515 (closes #4499). The shell now folds separators and case on Windows before comparing. If you saw a fine-tune disappear every time you reopened the app, upgrade to this release.A fine-tune vanished after an engine restart (pre-4510)
A fine-tune vanished after an engine restart (pre-4510)
/train/runs returning [] while the trainer kept the GPU — and start was willing to launch a second trainer beside the live one. Fixed in PraisonAI #4510: the run’s state and pid are persisted to runs/<run-id>/run.json at every transition, and the next engine boot rebuilds history from disk. A run is adopted only when its recorded pid and its start-time fingerprint still match the live process; an interrupted run whose pid is gone reads as failed, not missing. If you saw a run disappear across a restart, upgrade.Adopting purely on a live pid was itself a hazard — pids are recycled, and adopting a recycled one left the run pinned running forever (start refused every new fine-tune until someone deleted run.json by hand) while Stop SIGTERM’d whatever unrelated program now held that pid. PraisonAI #4680 added the start-time fingerprint (pid_start) so adoption proves ownership before reattaching; a pre-upgrade state file with no fingerprint is refused rather than adopted, at the cost of at most one run shown as interrupted across a single restart after upgrade. If fine-tuning was wedged with no live process, this is fixed — you no longer need to delete run.json by hand.Every training Start refused with 409 until an engine restart (pre-4509)
Every training Start refused with 409 until an engine restart (pre-4509)
OSError during log writing abandoned the pipe while the trainer was still writing. The child blocked on a full pipe, proc.wait() blocked on the child, run.finish() never ran, and the run’s state stayed running forever — so POST /train/start returned 409 for every subsequent run until the engine was restarted.Fixed in PraisonAI #4509 (closes #4493). The reader now always drains the pipe, log errors are caught per-line, and every line is flush()ed so train.log is the live full record. If you saw a run pinned to running and every subsequent Start refused, upgrade.Quitting the app orphaned a running fine-tune (pre-4508, macOS/Linux)
Quitting the app orphaned a running fine-tune (pre-4508, macOS/Linux)
init, kept the GPU, and became invisible to the app.Fixed in PraisonAI #4508 (closes #4491). The engine’s exit handler now calls Trainer.stop() before exiting, sending SIGTERM to the trainer’s own session/group. Windows was already correct (taskkill /T) and is unaffected. If you saw the GPU stay pinned after quitting on macOS or Linux, upgrade.Point the engine at a local praisonai-agents checkout
Point the engine at a local praisonai-agents checkout
PRAISONAI_AGENTS_SOURCE to your checkout before launching:praisonai-agents/ or src/praisonai-agents/. Earlier builds used a fixed path that resolved to a nonexistent directory from the bundled copy, so any local fix appeared to have no effect — that is now fixed.engine failed: address in use
engine failed: address in use
Address already in use). Quit the other process, or reset the engine and relaunch.engine failed: crashed
engine failed: crashed
No virtual environment found
No virtual environment found
src/praisonai-agents/.venv, src/praisonai-agents/venv, then venv. Create one of these and install praisonaiagents into it.Launched, but ExitCode=0 and no window (Windows)
Launched, but ExitCode=0 and no window (Windows)
0 after raising the existing window into the tray, so a bare Start-Process -PassThru reads that as a crash. Open %TEMP%\PraisonAI-startup.log: a secondary line for that pid confirms the launch was handed off cleanly and the primary is still running — check the system tray. If no line was written at all, the shell died before it could even trace itself; attach the missing log path to a bug report."Open at login" won't stay on
"Open at login" won't stay on
.app bundle so the engine can register a LaunchAgent. When the app runs from a checkout, or on Windows or Linux, the OS refuses the request. As of PraisonAI #4507 the engine persists the honest result (false) instead of the request (true), the toggle snaps back to off, and the inline row message shows Only available in the installed app. If you’re on macOS and want to test it from a checkout, set PRAISONAI_APP_BUNDLE to your built .app path before launching. On an earlier release, upgrading is the fix — pre-4507 the toggle would render on and survive restarts while no login item existed anywhere.no_answer, auth, rate_limit, internal) and after Stop — one turn produces at most one banner.Updates
The update check asks PyPI what the newestpraisonaiagents is: GET /update hits https://pypi.org/pypi/praisonaiagents/json and reports whether a newer release exists.
check_updates toggle controls whether the app checks on startup and from About → Check for updates now. A check that did not happen reports checked: false rather than falsely reading as “up to date”.
praisonaiagents by re-running provisioning, or by upgrading your own pinned venv if you set PRAISONAI_PYTHON.The app does automatically reconcile its own venv to the requirement shipped with the current build (see Library fixes never reached an existing install (pre-4670)). So a raised floor in the shipped requirement reaches you on the next launch; a newer PyPI release beyond that floor still requires a manual step.Reset Recipe
Quit the app
Delete the lockfile
Relaunch
starting engine.Best Practices
Check the log before filing a ticket
Check the log before filing a ticket
Keep one PraisonAI process at a time
Keep one PraisonAI process at a time
Match the interpreter to its venv
Match the interpreter to its venv
.venv inside the checkout to avoid mismatches.
