Nanobot

Nanobot finds consolidation can forget messages it already advanced past

A Nanobot report says consolidation can truncate archive input while advancing the session cursor past the full batch. A proposed memory fix preserves the full input; a related archive-cap report shows failure can mutate session state before persistence.

← Back to homeOriginal source ↗

HKUDS/nanobot issue #5377 is the inspected primary source: “Bug: consolidation truncates archive input but advances past the full message batch.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- HKUDS/nanobot issue #5377 was created 2026-08-13T13:22:23Z and was open at inspection; its title is “Bug: consolidation truncates archive input but advances past the full message batch.” - HKUDS/nanobot PR #5379 was created 2026-08-13T13:45:30Z and was open at inspection; its title is “fix(memory): preserve full consolidation input.” - HKUDS/nanobot issue #5378 was created 2026-08-13T13:22:25Z and was closed at inspection; its title is “Bug: file-cap archive failure mutates the session before persistence.” - The repository reported 47040 stars, 707 open issues, default branch main, and last push 2026-08-15T19:21:31Z. - The latest tagged-release baseline checked was v0.3.0 published 2026-07-25T08:08:47Z.

What changed

HKUDS/nanobot issue #5377 reports: Bug Description Consolidator.archive() truncates the formatted conversation to the consolidation model's input-token budget, but its callers still advance Session.last_consolidated past the entire original message batch. Any messages or message suffixes removed by _truncate_to_token_budget() are therefore treated as archived even though they were never shown to the consolidation provider and were not written to memory/history.jsonl through the raw fallback path. This affects both token-triggered consolidation and idle-session compaction. Steps to Reproduce 1. Create a session containing a message large enough to exceed the consolidation input budget, followed by a message containing a unique marker. 2. Run Consolidator.compact_idle_session() with a small context window. 3. Capture the user content passed to provider.chat_with_retry(). 4. Reload the persisted session and inspect last_consolidated and memory/history.jsonl. Observed on current main: The unique marker was never supplied to the consolidator, but the session cursor advanced past it. The relevant path is: Consolidator.archive() formats all messages and truncates the resulting string. maybe_consolidate_by_tokens() subsequently sets last_consolidated = end_idx. compact_idle_session() subsequently sets last_consolidated = archive_end. Expected Behavior Consolidation progress should advance only through source content that was actually archived. If a batch exceeds the provider input budget, it should be processed in bounded sub-batches (including a safe strategy for a single oversized message), or the unprocessed suffix should remain eligible for

HKUDS/nanobot PR #5379 reports: Summary replace lossy consolidation truncation with lossless bounded chunks defer history writes until every chunk succeeds, preserving raw fallback behavior on failure cover token-triggered consolidation, idle compaction, oversized inputs, and Unicode chunk boundaries Testing uv run --no-sync ruff check nanobot/agent/memory.py nanobot/utils/helpers.py tests/agent/test_consolidator.py tests/utils/test_helpers.py uv run --no-sync pytest tests/utils/test_helpers.py tests/agent/test_consolidator.py tests/agent/test_auto_compact.py tests/agent/test_memory_store.py tests/agent/test_dream.py -q (210 passed) uv run --no-sync pytest -q (6190 passed, 51 skipped; 5 environment-specific failures reproduced on unmodified origin/main) Fixes #5377

HKUDS/nanobot issue #5378 reports: Bug Description Session.enforce_file_cap() mutates the live Session before invoking the configured archive callback. If that callback raises, SessionManager.save() propagates the error, but the caller's in-memory session has already discarded the overflow. A later successful save cannot retry the archive because the dropped messages are no longer present. This turns a transient archive failure into permanent conversation-history and long-term-memory loss. Steps to Reproduce 1. Create a SessionManager and a session containing 2,004 alternating user/assistant messages. 2. Configure set_file_cap_archiver() with a callback that raises an exception. 3. Call SessionManager.save(session) and catch the exception. 4. Replace the callback with a working archiver and save the same session again. 5. Reload the session from disk. Observed on current main: enforce_file_cap() calls the mutating retain_recent_legal_suffix() before calling on_archive(archive_chunk). The failed callback therefore leaves the live object in its trimmed state. Expected Behavior File-cap retention and overflow archival should be atomic from the caller's perspective. If the archive callback fails, the session's messages, last_consolidated, provider state, and timestamps should remain unchanged so the next save can retry without data loss. Relevant Logs nanobot Version main@af582246f141311d574551b7571a517bcc3df750 Python Version 3.12 Operating System Windows Channel / Platform Other (reproduced directly through SessionManager) LLM Provider Other (the failure is in the persistence callback boundary) Configuration (Optional) Additional Context A minimal

Why it matters

Compaction is destructive when the cursor and archived evidence disagree. A failed archive must not leave memory believing content was safely preserved. The operator test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.

Current

The primary record was open when captured on 2026-08-16. The tagged-release baseline was v0.3.0 published 2026-07-25T08:08:47Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/HKUDS/nanobot/issues/5377. Supporting records are https://github.com/HKUDS/nanobot/pull/5379 and https://github.com/HKUDS/nanobot/issues/5378. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Make archive persistence and cursor advance one transaction, retain a recoverable pre-state, and test truncation and file-cap failures with exact message counts. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.