MemtraceDOCS

Troubleshooting

Symptom-first fixes for the failures people actually hit: ONNX load errors, a "stuck" first run, port conflicts, pre-AVX2 CPUs, a tripped embed circuit breaker, deferred installs, and degraded auth.

Each section below is one symptom: what you're seeing, why it happens, and the exact fix. If you don't see your symptom here, run memtrace doctor first — it catches most stale runtime state on its own — then check the FAQ.

ONNX Runtime failed to load (exit 75)#

Symptom: memtrace start exits immediately with a nonzero code (75) during boot, before the banner settles — no UI ever opens.

Cause: boot runs an ONNX Runtime dlopen pre-flight before anything else. If libonnxruntime can't be loaded on this host, memtrace start hard-exits with code 75 rather than crashing later, mid-embedding, with a confusing stack trace.

Fix: either make the dylib loadable, or skip embeddings entirely and keep the structural graph (search by symbol/reference still works — only semantic search is off):

terminal
$ MEMTRACE_SKIP_EMBED=1 memtrace start
# Structural-only graph, zero ONNX/model dependency. Semantic search is
# off; everything else (index, graph, quality, impact) still works.

$ MEMTRACE_ORT_DYLIB_PATH=/path/to/libonnxruntime.dylib memtrace start
# Point at a manually-installed ONNX Runtime dylib if the bundled one
# won't load on this host.

This is not the pre-AVX2 case: a CPU baseline check runs earlier, before this dlopen pre-flight, and exits with a different code (78) and its own "this CPU does not support AVX2" message. If your CPU actually lacks AVX2, you'd see that exit-78 failure instead — see "Pre-AVX2 CPUs" below. Exit 75 means AVX2 is present and the dylib itself failed to load.

First run looks "stuck"#

Symptom: the very first memtrace start in a fresh install prints a line about downloading the embedding model, then goes quiet for a while. It looks hung.

Cause: it isn't hung. The first embed call triggers a one-time download of the default embedding model (jina-code, 768-dim) into ~/.memtrace/fastembed_cache, followed by one-time ONNX Runtime session initialization. Memtrace prints an explicit "First run — downloading embedding model" notice specifically so this silent stretch isn't mistaken for a crash. Subsequent starts skip all of it and boot warm.

COREML COMPILE IS NOT PART OF THIS BY DEFAULT

On Apple Silicon, an additional CoreML graph compile only happens if you've explicitly set MEMTRACE_ENABLE_COREML=1 — it is not part of the default first-run cost. Without that flag, the first run loads the model and runs on CPU.

Fix: wait it out once, or pre-pay the cost on your own schedule instead of a user's:

terminal
$ memtrace warmup
# Downloads + initializes the embedding model ahead of time, off the
# critical path. Run this once after install, or bake it into a CI /
# image-build step.

See memtrace warmup for what exactly gets pre-paid and when to run it.

Port 3030 conflicts / ghost supervisors#

Symptom: memtrace start reports the UI port is already in use, or a memtrace stop is immediately followed by the daemon coming back on its own.

Cause: either something else is listening on the configured UI port (default 3030), or a leftover OS-level supervisor — a launchd plist on macOS, a systemd user unit on Linux, or a registered Windows service — is respawning an old binary after you stop it. Stale PID files and a heartbeat-alive-but-HTTP-dead owner produce the same symptom.

Fix: memtrace doctor diagnoses all of these in one pass; --fix clears them non-interactively:

terminal
$ memtrace doctor
# Report only: running processes, stale PID/state files, ghost OS
# supervisors, UI port listeners, agent MCP setup. Nothing changes.

$ memtrace doctor --fix
# Stops discovered OS supervisors, terminates a dead-or-mismatched
# workspace owner, kills whatever is listening on the UI port, and
# removes stale PID/state files.

$ memtrace doctor --fix --purge-legacy
# Also deletes legacy Windows service / launchd plist / systemd unit
# artifacts so they can't respawn a stale owner after `memtrace stop`.
--FIX ACTS IMMEDIATELY, NO CONFIRMATION

doctor --fix terminates processes non-interactively — it never prompts. It's safe to run any time, but know that it will kill the workspace owner, port listeners, and OS supervisors it finds.

Full details, including why --purge-legacy requires --fix to do anything, live on the memtrace doctor page.

Pre-AVX2 CPUs#

Symptom: on an older x86_64 host (Ivy Bridge / Xeon E5 v2 era, or a VM exposing a restricted CPU feature set), memtrace start refuses to launch with a clear message that the CPU doesn't support AVX2 — rather than crashing with an illegal-instruction trap deep inside the runtime.

Cause: the bundled ONNX Runtime build requires AVX2. Memtrace checks for it at startup and refuses cleanly instead of segfaulting. Install-time, the npm installer probes for AVX2 support (/proc/cpuinfo on Linux, a PowerShell processor-feature check on Windows, sysctl on macOS) and picks a matching platform package automatically.

Fix: the auto-detected *-noavx2 package covers Linux x64 and Windows x64 hosts without AVX2. Force the selection explicitly if detection guesses wrong, or supply your own dylib for a host with no noavx2 package (e.g. pre-AVX2 macOS Intel):

terminal
$ MEMTRACE_FORCE_NOAVX2=1 npm install -g memtrace
# Force the no-AVX2 platform package regardless of what detection found.

$ MEMTRACE_FORCE_AVX2=1 npm install -g memtrace
# Force the standard AVX2 package (e.g. detection false-negative in a VM).

$ MEMTRACE_ORT_DYLIB_PATH=/path/to/libonnxruntime.so memtrace start
# Supply your own non-AVX2 ONNX Runtime build directly. This is the
# only escape hatch the startup gate honors — set the env var explicitly.
A DYLIB DROPPED NEXT TO THE BINARY IS NOT ENOUGH ON ITS OWN

On a pre-AVX2 host, the startup CPU-baseline check runs before ONNX Runtime resolution and exits unless MEMTRACE_ORT_DYLIB_PATH (or ORT_DYLIB_PATH) is explicitly set, or the binary is running from inside a *-noavx2 package. Simply placing a compatible dylib next to the binary and hoping auto-discovery finds it does not satisfy the gate — set the env var.

noavx2 packages exist for Linux x64 and Windows x64 only; a pre-AVX2 macOS Intel host has no shipped noavx2 package and must use the manual MEMTRACE_ORT_DYLIB_PATH workaround above.

Embed circuit breaker tripped#

Symptom: embedding calls start failing fast — no cold-start delay, just an immediate error — after a prior embedding failure (e.g. a memory-pressure kill during a CoreML compile, or a burst of ONNX errors).

Cause: the embed worker trips a circuit breaker after failures to stop hammering a broken embedding path. Once tripped, it's a shared safety mechanism — any command that needs embeddings (including memtrace warmup) can fail immediately without attempting to reload the model, even if the underlying cause has since cleared.

Fix: pre-pay the cold start so it never trips in normal operation, and reset it if it already has:

terminal
$ memtrace warmup
# Forces the full cold-start chain (download, ONNX session init, and
# CoreML compile if MEMTRACE_ENABLE_COREML=1 is set) once, ahead of time,
# so a real indexing run doesn't trip the breaker on a cold spike.

There is no embed reset-breaker CLI subcommand. Reset a tripped breaker with the embed_reset_breaker MCP tool, by sending the running process SIGUSR1, or by restarting Memtrace.

COREML MEMORY PRESSURE IS A COMMON TRIGGER

If the breaker keeps tripping on Apple Silicon with MEMTRACE_ENABLE_COREML=1 set, the CoreML graph compile (60–300s cold) may be getting killed under memory pressure. Unset MEMTRACE_ENABLE_COREML, or set MEMTRACE_DISABLE_COREML=1 as a hard override, and run memtrace warmup again.

Symptom: npm install -g memtrace completes cleanly, but no agent picked up the MCP server, skills, or hooks.

Cause: this is by design, not a bug. Touching user-global config (agent MCP registration, skills, Claude Code hooks) is consent-gated. A plain install with no consent signal defers that setup — exit 0, nothing touched. npm normally suppresses postinstall logs, so the install may only show npm's package summary. Local package provisioning, such as selecting the right platform runtime, always runs regardless.

Fix: complete setup explicitly, or pre-approve it before installing:

terminal
$ memtrace setup --yes
# Completes the consent-gated part of install: agent MCP registration,
# skills, hooks. Run without --yes first if you want to review the plan.

$ MEMTRACE_INSTALL_YES=1 npm install -g memtrace
# Pre-approve consent so a single install does everything in one pass.

Consent-approved installs snapshot every user-global file they mutate into a backup manifest, so memtrace uninstall can restore pre-install bytes later. Run memtrace uninstall before npm uninstall -g memtrace — npm v7+ never fires preuninstall for global packages, so the shim needs to run first.

Degraded auth mode#

Symptom: memtrace status or the MCP server reports a "degraded" auth state, but tools still respond.

Cause: a licensed install that can't currently reach memtrace.io — a network blip, not a rejection — boots (or keeps running) in degraded mode: it keeps serving tools and re-validates in the background every 15 minutes. Only a definitive server-side rejection (revoked, invalid, or suspended license — an HTTP 401/403) actually refuses to start.

Fix: usually nothing — it self-heals once connectivity returns. If it persists:

terminal
$ memtrace status
# Check auth_session state, MemDB mode, data dir, and owner PID.

$ memtrace auth login
# Re-run the device-flow sign-in if credentials are actually invalid
# rather than just unreachable.
USING ONE LICENSE KEY ON MULTIPLE MACHINES IS FINE

Degraded mode is never triggered by using the same key on more than one device — billing is by query credit, not by seat.

See memtrace auth and memtrace status for more on the auth lifecycle, or the FAQ for the same question in shorter form.

Too much noise in the graph#

Symptom: the indexed file count is far higher than expected, search returns fixture or generated-config noise, or embeddings feel slow because huge generated trees are in the graph.

Cause: paths that git tracks but Memtrace should skip — generated bindings, large fixtures, vendored deps, agent worktrees — are not covered by .gitignore alone.

Fix: add a repo-root .memtraceignore with gitignore-style patterns, or use the dashboard Files tab Add to .memtraceignore action for one-off exclusions. Check skip counters with memtrace status on the running daemon.

.memtraceignore
# Example: skip generated and fixture trees
generated/
tests/fixtures/
*.pb.go

After editing ignore rules, run an incremental memtrace index or use --clear for a full rebuild if orphaned symbols remain.