Skip to content

fix: detect ContextOverflowError by name and add init visibility#41

Merged
BYK merged 3 commits intomainfrom
fix/context-overflow-detection-and-init-visibility
Mar 20, 2026
Merged

fix: detect ContextOverflowError by name and add init visibility#41
BYK merged 3 commits intomainfrom
fix/context-overflow-detection-and-init-visibility

Conversation

@BYK
Copy link
Owner

@BYK BYK commented Mar 19, 2026

Problem

Two issues causing sessions to get permanently stuck with context overflow errors:

  1. isContextOverflow() misses OpenCode's compaction error: When a session overflows and OpenCode's built-in compaction also fails, the error has name: 'ContextOverflowError' with message 'Conversation history too large to compact'. Lore's detection only checked for 5 API-level message strings — none match this compaction error, so auto-recovery never triggers.

  2. Silent plugin initialization failures: Lore hasn't captured messages for any session since March 12. The plugin init fails silently because all lore logging is gated behind LORE_DEBUG, and OpenCode's plugin loader catches and swallows the error. Zero visibility into what's going wrong.

Fix

Part 1: isContextOverflow() name-based detection

Add error.name === 'ContextOverflowError' as the first check, before the message text pattern matching. This catches:

  • API-level context overflow (name=ContextOverflowError, message varies by provider)
  • OpenCode compaction overflow (name=ContextOverflowError, message='Conversation history too large to compact')
  • Any future ContextOverflowError variants

Part 2: Always-on init visibility

  • Wrap LorePlugin body in try-catch that logs the full error + stack trace via process.stderr.write before re-throwing
  • Add [lore] active: <path> success log at end of init (always-on, not gated by LORE_DEBUG)
  • If the active line never appears for a project, the init failed and the error message shows why

Tests

  • 4 new test cases for ContextOverflowError name matching (compaction overflow, any message, name-only, negative case for UnknownError/429)

BYK added 3 commits March 12, 2026 11:20
…handling

Bug 1: Worker sessions were reused across multiple LLM calls in
distillation and curation. Each call's assistant response with
reasoning/thinking parts accumulated in the session history. When the
next call sent the full history back, providers rejected it with
'Multiple reasoning_opaque values received in a single response'.

Fix: Delete the parent→worker mapping from the workerSessions Map
immediately after reading the response in all 4 functions
(distillSegment, metaDistill, curator.run, curator.consolidate). This
ensures each LLM call gets a fresh session. Worker session IDs are
kept in workerSessionIDs Set so shouldSkip() still recognizes them.

Bug 2: The recall tool's execute() had no try/catch. If any of the
three search calls (temporal.search, searchDistillations, ltm.search)
threw, the entire tool execution failed and returned nothing.

Fix: Wrap each search call in independent try/catch blocks so partial
results are returned even if one source fails. Errors are logged via
log.error() (always visible).
Almost every query in the codebase filters on (project_id, session_id)
but only single-column indexes existed, forcing SQLite to pick one and
scan the remaining rows for other conditions.

New compound indexes (schema version 6):
- temporal_messages(project_id, session_id) — 10+ queries
- temporal_messages(project_id, session_id, distilled) — undistilled()
- temporal_messages(project_id, distilled, created_at) — pruning
- distillations(project_id, session_id) — 8+ queries
- distillations(project_id, session_id, generation, archived) — gen0 ops

Drop redundant single-column indexes that are now left-prefixes:
- idx_temporal_project (prefix of idx_temporal_project_session)
- idx_temporal_distilled (low-selectivity, covered by compounds)
- idx_distillation_project (prefix of idx_distillation_project_session)
- Add error.name === 'ContextOverflowError' check to isContextOverflow()
  so it catches both API-level overflow and OpenCode's compaction overflow
  ('Conversation history too large to compact')
- Wrap LorePlugin body in try-catch with process.stderr.write for always-on
  error visibility (not gated by LORE_DEBUG)
- Add '[lore] active: <path>' startup log so silent init failures are
  immediately detectable
- Add 4 test cases for ContextOverflowError name matching
@BYK BYK enabled auto-merge (squash) March 19, 2026 20:02
@BYK BYK disabled auto-merge March 20, 2026 14:42
@BYK BYK closed this Mar 20, 2026
@BYK BYK reopened this Mar 20, 2026
@BYK BYK enabled auto-merge (squash) March 20, 2026 14:43
@BYK BYK merged commit 78db560 into main Mar 20, 2026
1 check passed
@BYK BYK deleted the fix/context-overflow-detection-and-init-visibility branch March 20, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant