Troubleshooting
Step-by-step fixes for the most common build, runtime, and integration issues with L.U.N.A.
Port 8899 conflict
Backend fails to start: ERROR: [Errno 10048] error while attempting to bind on address ('0.0.0.0', 8899)
Another process is already using port 8899. Find and stop it:
# Find the process holding port 8899
netstat -ano | findstr :8899
# Kill it by PID (replace 12345 with the actual PID from the output above)
taskkill /PID 12345 /Flsof -ti :8899 | xargs kill -9If you want to run Luna on a different port, set backend_port=9000 in your.env and update the Vite proxy in frontend/vite.config.ts to match.
Ollama connection refused
Chat fails silently or returns: httpx.ConnectError: All connection attempts failedin the backend logs.
1. Verify Ollama is running
# Start Ollama (it runs as a background service)
ollama serve
# Confirm it's reachable
curl http://localhost:11434/api/tags2. Verify your model is pulled
ollama list
# If your configured model isn't listed, pull it
ollama pull qwen2.5:7b
ollama pull nomic-embed-text3. Check config.py values
Confirm ollama_model in your .env exactly matches the model name shown in ollama list — including the tag (e.g. qwen2.5:7b not justqwen2.5).
4. Non-default Ollama host
If Ollama is running on a different machine or port, set:
ollama_base_url=http://192.168.1.50:11434If you're using OpenRouter, LM Studio, or another OpenAI-compatible API instead of Ollama, see the Environment page — the config keys are different.
ChromaDB errors
Backend starts but semantic search fails, or logs show:chromadb.errors.InvalidCollectionException or sqlite3.DatabaseError: database disk image is malformed
Reset the ChromaDB collection
The ChromaDB index can be rebuilt from the SQLite facts at any time. Deleting the folder triggers an automatic rebuild on next startup:
# Stop the backend first, then:
Remove-Item -Recurse -Force datachromarm -rf data/chromaThe next time Luna starts it will re-embed all facts from data/luna.db. For large fact collections this may take a few seconds.
Embedding model not available
ChromaDB silently skips embedding if the embedding model request fails. Confirm the embedding model is pulled in Ollama:
ollama pull nomic-embed-textWindows encoding errors (UnicodeEncodeError)
Backend crashes on Windows with:UnicodeEncodeError: 'charmap' codec can't encode character '✓'
Windows uses the cp1252 code page by default for console output, which cannot encode Unicode characters like ✓, →, or emoji. Fix this two ways:
Option A — Set UTF-8 mode (recommended)
Set the environment variable before starting the backend:
$env:PYTHONUTF8 = "1"
npm run luna -- devOr add it permanently to your system environment variables via Settings → Advanced → Environment Variables.
Option B — Patch the backend code
If you're adding new code that logs output, avoid non-ASCII characters in log messages. See the Contributing page — this is an enforced code standard.
# Bad — will crash on Windows cp1252
logger.info("✓ Memory loaded")
# Good
logger.info("Memory loaded successfully")Voice not working
Wake word not triggering
- Confirm
wake_word_enabled=trueis set in.env. - The wake word is case-insensitive. Default is
hey luna. Make surewake_wordin.envmatches what you're saying. - Check that
voice_runtimeshows asrunninginGET /api/system/processes. - Verify your default microphone is selected in OS audio settings.
Transcription is inaccurate
Switch to a larger Whisper model:
whisper_model=small # or medium for best accuracyLarger models use more RAM but transcribe more accurately. See theVoice page for the full tradeoff table.
TTS not speaking
- Confirm your OS volume is not muted.
- List available voices and check the index:
import pyttsx3
engine = pyttsx3.init()
for i, v in enumerate(engine.getProperty('voices')):
print(i, v.name)Set tts_voice_index in .env to a valid index from the output above.
Microphone permission denied
On Windows, go to Settings → Privacy → Microphone and ensure Desktop apps are allowed to access the microphone. On macOS, go to System Settings → Privacy & Security → Microphone.
Frontend blank screen
The Vite dev server starts but the browser shows a blank page or a white screen with no error.
1. Check the browser console
Open DevTools (F12) → Console. A React render error will be logged there with the exact component and line.
2. Verify the backend is running
The frontend makes an API call on mount. If the backend is down:
curl http://localhost:8899/health
# Should return: {"status":"ok",...}3. Check the proxy config
The Vite proxy at frontend/vite.config.ts forwards /api tohttp://localhost:8899. If your backend port differs, update the proxy target.
4. TypeScript errors blocking the build
cd frontend
npm run build # Shows all TypeScript errors5. Clear Vite cache
cd frontend
rm -rf node_modules/.vite
npm run devElectron crashes or won't start
The Electron window opens and immediately closes, or shows an error dialog about the backend failing to start.
Backend crash loop
Electron monitors the FastAPI backend and restarts it up to 3 times within 60 seconds. If all 3 attempts fail, it shows an error dialog and stops retrying.
Run the backend manually to see the error directly:
npm run luna -- backendWrong Python in PATH
Electron spawns Python directly. If your virtual environment is not activated, it may pick up the wrong Python without the required packages:
# Activate your venv before launching
.venvScriptsactivate # Windows
source .venv/bin/activate # macOS / Linux
npm run luna -- devElectron port conflict
Electron uses port 5173 for the Vite dev server renderer and 8899 for the backend. Both must be free. See the Port 8899 conflict section above.
Spotify auth issues
Spotify routes return 401 or the login flow redirects but shows"INVALID_CLIENT: Invalid redirect URI".
Redirect URI mismatch
In your Spotify Developer dashboard, the redirect URI must be set to exactly:
http://localhost:8899/api/spotify/callbackNo trailing slash. No https. It must match character-for-character.
Token expiry
The Spotify token is stored at data/spotify_token.json. If it has expired and the refresh fails, delete the file and re-authenticate:
# Delete the stale token
del dataspotify_token.json
# Re-authenticate by visiting
curl http://localhost:8899/api/spotify/loginMissing credentials
Ensure both spotify_client_id and spotify_client_secret are set in .env. See the Environment page.
Memory not persisting between sessions
Luna doesn't remember facts from previous conversations after a restart.
1. Verify fact extraction is running
Facts are extracted by the memory_maintenance background process, which runs every 5 minutes. Check it's active:
curl http://localhost:8899/api/system/processes | python -m json.toolLook for "name": "memory_maintenance" with "status": "running".
2. Check that data/ is not being deleted
data/luna.db is where facts live. If you're running npm run luna -- cleanfrequently, that command does not touch data/ — but manual deletion would. Confirm the file exists:
# Windows
dir dataluna.db
# macOS / Linux
ls -lh data/luna.db3. Cold start period
On first run there are no facts. The extractor needs a few conversations before memory becomes useful. After 3–5 sessions, context quality improves noticeably.
Build failures
Frontend TypeScript errors
cd frontend && npm run buildRead each error carefully — they always include the file path and line number. Common causes:
- Missing type imports after adding a new component.
anytype added to bypass a type error — find and fix the root type.- A new API response shape that doesn't match
frontend/src/types/index.ts.
Backend syntax errors
npm run luna -- checkRuns python -m py_compile on critical backend files. Catches import errors and obvious syntax mistakes immediately.
npm install fails
# Clear npm cache and reinstall
npm cache clean --force
npm installpip install fails
Ensure you're inside an activated virtual environment and that you have the required Python version (3.10+):
python --version # Must be 3.10 or newer
pip install --upgrade pip # Update pip first
pip install -r backend/requirements.txtRun npm run luna -- doctor first — it checks Node.js, npm, and Python versions and tells you exactly what's wrong with your environment.