Skip to content

fix(compression): fall back to replace_messages when archive_and_compact fails (#71097)#71115

Open
JonthanaHanh wants to merge 1 commit into
NousResearch:mainfrom
JonthanaHanh:fix/hygiene-in-place-compaction-flag
Open

fix(compression): fall back to replace_messages when archive_and_compact fails (#71097)#71115
JonthanaHanh wants to merge 1 commit into
NousResearch:mainfrom
JonthanaHanh:fix/hygiene-in-place-compaction-flag

Conversation

@JonthanaHanh

Copy link
Copy Markdown
Contributor

Problem

When archive_and_compact() raises during in-place compaction (contended write, schema-migration race, etc.), the broad except Exception at the end of the compress_context try block swallows the error. compacted_in_place stays False, so _last_compaction_in_place is never set. The gateway then enters the else branch and discards the successfully-produced summary with the "no session_db on the hygiene agent" warning.

Fix

Wrap the archive_and_compact() call in its own try/except. When it raises, fall back to replace_messages(active_only=True) so the compressed transcript is still persisted. This is destructive relative to archive_and_compact (loses soft-archived pre-compaction history) but is strictly better than silently dropping the compression result.

Regression test

TestInPlaceArchiveFailureFallback.test_archive_and_compact_failure_falls_back_to_replace — patches archive_and_compact to raise RuntimeError("database is locked"), runs compress_context, verifies:

  • Live transcript is the compacted 2-message set
  • _last_compaction_in_place is True

Fixes #71097

…act fails (NousResearch#71097)

archive_and_compact can raise on contended writes or schema-migration
races. Previously the broad except swallowed the error, leaving
compacted_in_place=False and causing the gateway to discard the
successfully-produced summary.

Fixes NousResearch#71097
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint area/compression Context compression and continuation sessions area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 25, 2026
@PRATHAMESH75

Copy link
Copy Markdown
Contributor

I filed the needs-info diagnosis on #71097, so I verified this fix against that root-cause trace and it lands on exactly the right branch. This correctly fixes the issue.

Root cause match. On upstream/main, agent._session_db.archive_and_compact(...) at agent/conversation_compression.py:1497 runs before split_status = "in_place_committed" (1498) and compacted_in_place = True (1508). If archive_and_compact raises (contended write / migration race), control unwinds to the outer except, so compacted_in_place stays False and agent._last_compaction_in_place = compacted_in_place (1751) records False — even though a summary was produced. That is the exact "compression executed successfully but the flag never set" symptom in the report. Wrapping the archive call and falling back to replace_messages(active_only=True) keeps execution on the in_place_committed path, so the flag is set and the gateway consumes the result instead of discarding it. ✅

Verified locally. tests/run_agent/test_in_place_compaction.py::TestInPlaceArchiveFailureFallback passes, and it's load-bearing: the assert agent._last_compaction_in_place is True at the end fails on unpatched main (the swallowed exception leaves it False), so the test genuinely pins the regression rather than the happy path.

One non-blocking note. The fallback replace_messages shares the same DB/connection as the failed archive_and_compact, so a persistent lock (rather than a transient contended write) would make it raise too and re-propagate to the outer except — back to the original symptom. In practice the single-statement replace is far likelier to succeed than the multi-statement archive transaction, and the destructive-but-persisted trade-off you documented is the right call, so this isn't a blocker — just worth a follow-up log-and-continue if the fallback itself fails, so a hard-locked DB degrades to "history kept, flag unset" rather than an unhandled raise.

Nice, tightly-scoped fix with a real regression test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/compression Context compression and continuation sessions area/sessions Session lifecycle, resume, persistence, history comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hygiene Agent In-Place Compression Fails: _last_compaction_in_place Not Set

3 participants