
61 issues were fixed in the v3.1.0 release cycle, summarized below by severity.
| # | Issue | Resolution |
|---|---|---|
| 1 | Orphaned SSE streams exhausting file descriptors | Added stream lifetime tracking with context cancellation |
| 2 | Arbitrary file read via path traversal in import | Sanitized paths with filepath.Clean and base directory validation |
| 3 | Config race condition on api.base_url |
Moved config reads behind sync.RWMutex |
| 4 | Config race condition on identity fields |
Merged identity reads into the existing mutex guard |
| 5 | Goroutine leak in SSE broadcaster | Added sync.WaitGroup with done channel on client disconnect |
| 6 | Goroutine leak in WebSocket handler | Added read deadline and context cancellation |
| 7 | Goroutine leak in agent tool execution | Added tool-level context propagation |
| 8 | Unbounded memory growth in session cache | Added LRU eviction with max size of 1000 sessions |
| 9 | Config file corruption on concurrent writes | Switched to atomic write (write-temp + rename) |
| 10 | Panic on nil embedding model | Added nil check with fallback to default model |
| 11 | Deadlock in sync merge when DB is locked | Added busy timeout and retry loop |
| 12 | SQL injection via conversation search query | Switched to parameterized queries |
| 13 | Memory leak in HTTPS client connection pool | Added http.Transport with max idle conns and timeout |
High-severity fixes included: goroutine leak in memory indexer, config file world-readable permissions, weak AES key derivation (upgraded to Argon2id), concurrent session mutation during sync, panic on malformed embedding response, CORS misconfiguration allowing any origin, missing input validation on API endpoints, stale config values after hot-reload, race on llama process handle, and 6 others.
Medium-severity fixes included: background goroutine error swallowing, session file permissions after creation, SSE missing DONE chunk on stream end, embedding batch size causing OOM on small models, empty conversation names in sidebar, websocket reconnection flood, agent loop spinning on error, and 6 others.
Low-severity fixes included: config file not found causing silent defaults, memory index returning stale results after delete, unchecked type assertions in provider code, missing request ID in log lines, deprecated ioutil usage replaced with io/os, inconsistent error wrapping, typos in CLI help text, unused imports, and 13 others.
A stability and trust-focused pass, found and fixed across several releases leading up to v3.3.3.
| # | Issue | Resolution |
|---|---|---|
| 1 | /remember silently saved nothing, ever |
One-character bug in the database insert fixed; covered by a regression test |
| 2 | Memory could stay off after a restart | Backend now detects an already-running embedding server on startup and reconnects instead of talking to a placeholder |
| 3 | Keyword-based memory search never actually activated in any release | Fixed startup wiring so vector + FTS5 search genuinely run together |
| 4 | Multi-topic questions returned incomplete answers | Each topic in a multi-part question is now searched independently instead of blended into one query |
| 5 | Claude provider could send chat messages with an empty model field | Fallback-to-configured-model logic is now actually applied; regression test added; Gemini and other providers confirmed unaffected |
| 6 | Symlink sandbox-escape in file-editing tools | A symlink inside a project pointing at a not-yet-existing file could let a tool write outside the sandbox; closed |
| 7 | Remote access (LAN/ngrok) accepted requests with no credentials | Every request now requires the access token shown in Settings |
| 8 | Dangerous-command filter had gaps | Hardened pattern matching for destructive commands (e.g. wiping root/home) |
| 9 | govulncheck findings in golang.org/x/text / x/net |
Dependencies bumped to patched versions |
| 10 | SSE terminal chunk silently dropped ~50% of the time on cancellation | Non-blocking send/receive tried first in every stream layer before falling back to a ctx-aware select |
| 11 | Double-send race could dispatch two overlapping requests for one send | isSendingProvider claim moved before the first await in MessagesNotifier.sendMessage() |
| 12 | .memo backup missing calendar, routines, task lists, agent permissions, skills, and machine.key |
Backup now includes all of these (models remain optional via their own toggle) |
| 13 | Agent mode could fail with 400 invalid_request_error against some external providers |
An internal bookkeeping field leaking into tool definitions was removed |
| 14 | a.client/providerRouter reassignment during active streams |
Re-verified: both reads and writes are correctly mutex-guarded; the narrower in-flight-request risk was fixed with clientSwapped/providerSwapped checks |
| 15 | No API versioning prefix | The server now mirrors every route under /api/v1/ alongside the original paths |
A reliability and polish pass focused on background-task crash safety and a reported 4-5x local generation slowdown.
| # | Issue | Resolution |
|---|---|---|
| 1 | An unexpected error in almost any background task could crash the entire backend | Every background task (memory, streaming, WhatsApp, cloud sync, local model management, STT, routines, proactive suggestions, notifications, remote-access tunnels) is now guarded and recovers in isolation |
| 2 | Memory/RAG being on could cut local generation speed 4-5x | The embedding server no longer auto-sizes itself onto the GPU against an already-resident chat model; defaults to CPU-only, removing the VRAM contention |
| 3 | Unbounded memory-context token budget | Capped at a real ceiling instead of a practically-unbounded one |
| 4 | Agent mode could fail on a single-word message with a small-context local model | Agent mode's tool schema is now correctly budgeted against the model's context size; default local context raised 4096→8192 |
| 5 | "Delete All Data" could fail on Windows | Internal databases are now properly closed before their files are removed |
| 6 | Speech-to-text couldn't find its bundled files from an installed CLI | Fixed the binary search path for installed (not just desktop) launches |
| 7 | Clean Windows installs could fail with a missing msvcp140.dll |
Installer now bundles and silently installs the Visual C++ Redistributable |
| 8 | Web search fired on every single message, even greetings | web_search tool. See Agent Mode. |
| 9 | A new chat message could queue behind background memory work on local models | A real chat message now cancels any in-flight background memory call first |
| 10 | govulncheck finding in google.golang.org/grpc |
Dependency patched |
The self-hosting release — a full 4-mode auth system, multi-account support, Docker/CasaOS, and a complete CLI management toolkit, plus a mobile-responsive pass and an Orchestra+Agent architectural fix. A large share of the self-hosting bugs were found live on a real Raspberry Pi across several SSH sessions, not by reading code.
| # | Issue | Resolution |
|---|---|---|
| 1 | Remote access was one shared token compared against on every request | Replaced with a full 4-mode auth system (none/token/password/token+password), argon2id hashing, brute-force lockout, per-device tokens |
| 2 | First screen after connecting to a fresh self-hosted backend could get permanently stuck on a generic error if it landed before login finished | Every affected screen's request now retries once the auth gate opens, instead of giving up for good |
| 3 | Uninstalling and reinstalling a self-hosted server silently kept the old account | The systemd service now points at the correct data directory the uninstaller actually deletes |
| 4 | Reported LAN address after install could be an unrelated Docker/VPN bridge IP | Address detection now uses the box's real default-outbound-route IP |
| 5 | An ISP-level cache could keep serving a stale installer binary indefinitely | Install/update scripts now cache-bust their own download |
| 6 | Deleting and recreating a self-hosted server could leave the browser stuck believing setup was already done | The setup gate now recognizes a genuinely fresh install (new server-side install ID) and clears stale local state |
| 7 | The first-run "token-only" setup option 401'd unconditionally from any non-server device | Fixed and confirmed live against a real non-loopback client |
| 8 | CORS origin-validation bypass in the remote-access gate (CWE-346) | Closed |
| 9 | govulncheck finding GO-2026-6218 in Go's net/url |
Go toolchain bumped to the patched release |
| 10 | Agent mode (tool use) silently ignored by the non-streaming POST /api/send path |
Now routes through the same agent-aware pipeline as streaming chat |
| 11 | Orchestra Mode + Agent Mode together never actually shared tool access — a task could only claim to have "simulated" a tool call | Each Orchestra task now runs through the same real, sandboxed, permission-gated agent pipeline a direct agent chat uses |
| 12 | Task Loop's "start" silently did nothing — 0 of N done forever, no worker ever called | The background run loop no longer inherits the HTTP request's context, which was being cancelled the instant the handler returned |
| 13 | Orchestra's internal utility calls (chat titles, routine parsing) were forced through the full plan→execute→synthesize pipeline | Added a direct single-completion path that bypasses task planning for these |
| 14 | Agent permission dialog's countdown (5 min) disagreed with the backend's real auto-deny timer (60s), and could get permanently stuck open | Countdown matched to 60s on both sides; dialog now also checks the current send state on every build, not just on a live transition |
| 15 | Routine confirmation's WhatsApp/Phone delivery chips were decorative, not interactive | Switched to toggleable FilterChips |
| 16 | Chat didn't show a message that ended in a backend-reported error until a manual page reload | refresh() now runs on that path, matching every other terminal path |
| 17 | 10+ mobile-width layout overflows across Chat, Settings, Model Store, Agent, Calendar, the welcome tip, and the setup wizard | Each reproduced live in a real 375px browser session and fixed individually — drawers for fixed sidebars, scrollable header rows, a stacked composer, responsive dialog widths |
Total: 61 fixes in the v3.1.0 cycle (13 critical, 15 high, 13 medium, 20 low), plus 15 additional fixes in the v3.3.3 cycle, plus 10 additional fixes in the v3.3.4 cycle, plus 17 additional fixes in the v3.5.5 cycle above.