long_term_memory: true without an embedding model crashes the entire server (unrecovered panic in saveCurrentConversation)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 49.2k
- Forks
- 4.5k
- Avg merge
- 1d 3m
- Merged PRs (30d)
- 239
Description
Hi,
This is found and redacted by Claude, as I'm fucking unable to explain it better.
It's not a code review, but an actual crash I encountered while I let it work for me.
LocalAI version:
localai/localai:v4.9.0-gpu-nvidia-cuda-13 (LocalAI v4.9.0, commit f7ad3f70eb5d8a0ddf80e08557f0d7df28cf032e; vendored github.com/mudler/LocalAGI v0.0.0-20260606071251-14aed1ae4336)
Environment, CPU architecture, OS, and Version:
Linux ia 6.8.0-139-generic #139-Ubuntu SMP PREEMPT_DYNAMIC Sat Aug 1 03:52:05 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Bare-metal host (not a VM), Ubuntu 24.04.4 LTS, NVIDIA GeForce RTX 3090, driver 580.173.02, CUDA 13.0. Running via Docker Compose with runtime: nvidia. Backend: llama-cpp / cuda13-llama-cpp.
Describe the bug
Creating an agent via POST /api/agents (or PUT /api/agents/{name}) with "long_term_memory": true but without an embedding model installed/configured causes an unrecovered Go panic (nil pointer dereference) the first time that agent finishes a chat job and the framework tries to save the conversation. The panic is not scoped to the misconfigured agent's own goroutine — it crashes the entire local-ai process (PID 1 in the container). Docker's restart policy (unless-stopped) then restarts the container, which wipes the in-memory observables/job history for every agent on the instance (not just the misconfigured one) and briefly takes the whole API down for all users/agents while it reloads.
Root cause appears to be that long_term_memory depends on an embedding model (default seems to be granite-embedding-107m-multilingual, built-in chromem vector store) that was never installed on this instance, and the save-conversation code path dereferences it without a nil check.
To Reproduce
- Start LocalAI v4.9.0 with the agent pool enabled (default) and no embedding model installed (fresh instance, or one where
granite-embedding-107m-multilingualwas never pulled via the gallery). - Create an agent:
curl -X POST http://localhost:8080/api/agents \ -H "Content-Type: application/json" \ -d '{ "name": "test-agent", "model": "<any working chat model>", "system_prompt": "You are a test agent.", "api_url": "http://localhost:8080/v1", "api_key": "sk-local", "long_term_memory": true }' - Send it a chat message:
curl -X POST http://localhost:8080/api/agents/test-agent/chat \ -H "Content-Type: application/json" \ -d '{"message": "hello"}' - Wait for the model to generate a response and for the framework to attempt saving the conversation — the whole server crashes and restarts a few seconds later.
Expected behavior
The API should return an error for that specific request/agent (e.g. "long_term_memory requires an embedding model / knowledge base to be configured"), and the rest of the server (other agents, in-flight requests) should be unaffected. At minimum, the panic should be recovered at the job/goroutine level so one misconfigured agent can't take down the whole process.
Logs
Saving conversation agent="supervisor" conversation size=4
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0xf9a3a9]
goroutine 7150 [running]:
github.com/mudler/LocalAGI/core/agent.(*Agent).saveCurrentConversation(0x1c1dad1543c0, {0x1c1da66b8f08, 0x4, 0x1c1da591c730?})
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/agent/knowledgebase.go:176 +0x629
github.com/mudler/LocalAGI/core/agent.(*Agent).consumeJob.func8({0x1c1da66b8f08?, 0x4?, 0x4?})
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/agent/agent.go:1420 +0x28
github.com/mudler/LocalAGI/core/types.(*JobResult).Finish(0x1c1da50fd290, {0x0?, 0x0?})
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/types/result.go:43 +0xdf
github.com/mudler/LocalAGI/core/agent.(*Agent).consumeJob(0x1c1dad1543c0, 0x1c1da566e180, {0x48076fd, 0x4})
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/agent/agent.go:1423 +0x2b27
github.com/mudler/LocalAGI/core/agent.(*Agent).run(0x1c1dad1543c0, 0x1c1da4854e70)
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/agent/agent.go:1543 +0xfd
github.com/mudler/LocalAGI/core/agent.(*Agent).Run.func1()
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/agent/agent.go:1521 +0x3a
created by github.com/mudler/LocalAGI/core/agent.(*Agent).Run in goroutine 6913
/root/go/pkg/mod/github.com/mudler/!local!a!g!i@v0.0.0-20260606071251-14aed1ae4336/core/agent/agent.go:1520 +0x1db
docker inspect on the container right after the crash showed ExitCode=0, OOMKilled=false, Error="", and docker events showed a die event with no preceding kill/stop action — confirming this is the process self-terminating on the panic, not an external kill/OOM.
Additional context
Workaround that resolves it: install an embedding model first (POST /models/apply with {"id": "localai@granite-embedding-107m-multilingual"}), then set both long_term_memory: true and enable_kb: true together on the agent (long_term_memory alone is not enough / is what triggers the crash). Retested with the same repro steps after applying the workaround: no panic, container RestartCount unchanged, GET /api/agents/collections shows a collection for the agent, and the job's observables history shows a clean "Recall" step (KB auto-search) before the actual response.
Found while building a multi-agent setup (Planner/Coder/Reviewer/Supervisor) on top of LocalAI's native agent pool.
Regards
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in knowledgebase.go at Agent.saveCurrentConversation, then trace the callback through agent.go's consumeJob and result.go's JobResult.Finish. Reproduce with long_term_memory enabled and no embedding model or knowledge base, and verify that the misconfigured request reports an error without terminating the server or affecting other agents.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- ai, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100