openclaw - ✅(Solved) Fix Plugin-owned context engines (ownsCompaction) run compaction with no safety timeout — host can hang the agent indefinitely [3 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#84077Fetched 2026-05-20 03:44:20
View on GitHub
Comments
2
Participants
2
Timeline
18
Reactions
1
Timeline (top)
labeled ×7cross-referenced ×4commented ×2mentioned ×2

When a plugin-owned context engine — one that advertises ownsCompaction: true (e.g. the lossless-claw / LCM plugin) — handles compaction, OpenClaw awaits the engine's ContextEngine.compact() with no timeout, no watchdog, and no abort signal, across five distinct call sites. The 900 s safety timeout (compactWithSafetyTimeout / EMBEDDED_COMPACTION_TIMEOUT_MS) that protects native pi-agent-core compaction was never applied to the plugin-owned lanes.

If a plugin engine's compact() is slow or hangs, the agent turn is unresponsive for the entire duration. The only backstop is the default 48-hour agent run timeout — and even that cannot interrupt the plugin call, because ContextEngine.compact() has no abortSignal in its contract.

User-visible symptom: "the agent stopped responding right after it started compacting."

A second, independent host-side gap in the same area — unbounded before_compaction / after_compaction hooks — is documented under Related host-side gap below.

Error Message

Each site has a try/catch that converts a thrown compact() error into a clean { ok: false } result — but a hang (a promise that never settles) is not a throw, so the catch does nothing for it.

  • Expected: plugin-owned compaction is bounded by the same safety timeout as native compaction; on timeout the host fails the compaction cleanly (surfacing an error and/or falling back) instead of hanging the turn.

Root Cause

compactWithSafetyTimeout (src/agents/pi-embedded-runner/compaction-safety-timeout.ts, EMBEDDED_COMPACTION_TIMEOUT_MS = 900_000) does exist and is applied — but only around the native activeSession.compact() call inside compactEmbeddedPiSessionDirectOnce. A plugin engine that owns compaction bypasses delegateCompactionToRuntime and therefore never reaches that wrapper.

Verified: the installed 2026.5.18 dist chunk containing the contextEngine.compact() call sites has zero references to compactWithSafetyTimeout.

Aggravators:

  • ContextEngine.compact() (src/context-engine/types.ts) has no abortSignal parameter. A run-level abort (abortRunactiveSession.abortCompaction()) only aborts the native session — a plugin compact() in flight receives no cancellation.
  • waitForCompactionRetryWithAggregateTimeout re-arms indefinitely while isCompactionStillInFlight() is true, so its 60 s aggregate timeout degrades to an infinite wait if a compaction_start is never matched by a compaction_end.

Fix Action

Fix

  • compact() no-timeout (this issue): PR openclaw/openclaw#84083 — adds a compactContextEngineWithSafetyTimeout helper and wraps all five ownsCompaction compact() call sites; adds an optional abortSignal to the ContextEngine.compact() contract and threads the run abort signal through. The helper is shared with the codex extension via the openclaw/plugin-sdk/agent-harness-runtime surface (one implementation, no copy-paste).
  • Compaction-hook no-timeout (the related gap): PR openclaw/openclaw#84153 — adds before_compaction / after_compaction default entries (30 s) to DEFAULT_VOID_HOOK_TIMEOUT_MS_BY_HOOK.

PR fix notes

PR #84083: fix(agents): bound plugin-owned context-engine compaction with a safety timeout

Description (problem / solution / changelog)

Summary

A plugin context engine that advertises ownsCompaction: true (e.g. the lossless-claw LCM plugin) had its ContextEngine.compact() awaited by the host with no timeout, no watchdog, and no abort signal on every engine-owned compaction lane — both the built-in pi-embedded runner and the codex agent harness:

  • queued /compact (compact.queued.ts)
  • context-overflow / force-compaction recovery (run.ts)
  • timeout recovery (run.ts)
  • context-engine-owned Codex compaction (extensions/codex/.../compact.ts)
  • Codex force-compaction-on-overflow recovery (extensions/codex/.../run-attempt.ts)

The 900 s compactWithSafetyTimeout safety net (EMBEDDED_COMPACTION_TIMEOUT_MS) that protects native pi-agent-core compaction was only ever applied to the native activeSession.compact() call. A slow or hung plugin compact() would hang the agent turn indefinitely — the only backstop was the 48 h default run timeout, which could not even interrupt the plugin call. The two codex-harness sites already had a try/catch that converts a thrown compact() error to a clean { ok: false } result, but a hung promise that never settles was not caught.

Changes

  • Add a compactContextEngineWithSafetyTimeout helper that wraps a plugin ContextEngine.compact() in the same finite, host-resolved safety timeout used for native compaction.
  • Wire it into all five engine-owned contextEngine.compact() call sites:
    • pi-embedded runner — queued /compact (compact.queued.ts), context-overflow recovery and timeout recovery (run.ts).
    • codex agent harnesscompactOwningContextEngine (extensions/codex/src/app-server/compact.ts) and forceContextEngineCompactionForCodexOverflow (extensions/codex/src/app-server/run-attempt.ts). These are the lanes a codex-harness agent with an ownsCompaction plugin actually uses.
  • Export compactContextEngineWithSafetyTimeout (+ resolveCompactionTimeoutMs) through the existing openclaw/plugin-sdk/agent-harness-runtime surface that the codex extension already imports, so the host and the codex harness share one implementation rather than copy-pasting the watchdog across the package boundary.
  • Add an optional abortSignal to the ContextEngine.compact() contract. The run's abort signal is both raced against the call (so a non-cooperating engine is still bounded) and threaded into the compact() params (so cooperating engines can cancel their own in-flight work). The codex sites thread params.abortSignal (compact.ts) and the run-level runAbortController.signal (run-attempt.ts).
  • On timeout/abort the queued lane and both codex-harness lanes surface a clean { ok: false } result — matching how the overflow/timeout run lanes already convert a thrown compact() — instead of hanging or throwing a raw rejection at callers.

This is additive to feat/context-engine-intercept-compaction, which covers the separate codex session_before_compact intercept lane (interceptsCompaction); this PR covers the ownsCompaction queued/overflow/timeout lanes across both the pi-embedded runner and the codex harness.

Fixes #84077

Test plan

  • pnpm tsgo:core + pnpm tsgo:core:test clean
  • pnpm tsgo:extensions + pnpm tsgo:extensions:test clean
  • oxlint clean on all changed files; plugin-sdk boundary checks pass
  • New unit tests: a plugin compact() exceeding the timeout is bounded and rejects with a timeout error; the abort signal is threaded into compact() params; abort fires before timeout and rejects promptly
  • New integration tests: queued lane converts a hung/throwing compact() to a clean ok:false; run abort signal reaches engine-owned overflow compaction
  • New codex-harness tests: a hung owning-engine compact() in the Codex compaction lane is bounded and surfaces as ok:false; a hung compact() during Codex overflow recovery is bounded so the run still proceeds; the caller / run-level abort signal is threaded into the codex-harness compact()
  • Existing pi-embedded compaction suites pass (118 tests across the 5 affected files); existing codex compaction suites pass

Real behavior proof

Behavior addressed: hung ownsCompaction context-engine compaction no longer waits forever. The host timeout now both bounds the await and aborts the signal passed into contextEngine.compact(), then returns a clean failed compaction result.

Real environment tested: local OpenClaw checkout /Volumes/LEXAR/repos/openclaw-fix-owns-compaction-timeout, branch fix/owns-compaction-safety-timeout, head b5a35b16b55, Node via node --import tsx, actual extensions/codex/src/app-server/compact.ts and src/agents/pi-embedded-runner/compaction-safety-timeout.ts.

Exact steps or command run after the patch: created a real Codex app-server session binding under /Volumes/LEXAR/Codex/pr-84083-proof, supplied an owning context engine whose compact() never settles, configured agents.defaults.compaction.timeoutSeconds=1, invoked maybeCompactCodexAppServerSession(), and captured whether the signal delivered to compact() aborted when the safety timeout fired.

Evidence after fix:

{
  "branch": "fix/owns-compaction-safety-timeout",
  "head": "b5a35b16b55",
  "behavior": "hung ownsCompaction contextEngine.compact() receives a host timeout abort signal and returns bounded failure",
  "elapsedMs": 1088,
  "compactCalls": 1,
  "receivedAbortSignal": true,
  "signalAborted": true,
  "signalReason": "Compaction timed out",
  "result": {
    "ok": false,
    "compacted": false,
    "reason": "context engine compaction failed: Compaction timed out"
  }
}

Observed result after fix: the hung owning engine returned through the host safety timeout in about 1.1 seconds, the engine saw an AbortSignal, that signal aborted with Compaction timed out, and the caller received { ok: false, compacted: false } instead of hanging.

What was not tested: a real third-party plugin process wedged in production; this proof uses the in-process context-engine interface with an intentionally never-settling compact() implementation.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/.generated/plugin-sdk-api-baseline.sha256 (modified, +2/-2)
  • extensions/codex/src/app-server/compact.test.ts (modified, +108/-11)
  • extensions/codex/src/app-server/compact.ts (modified, +23/-11)
  • extensions/codex/src/app-server/run-attempt.context-engine.test.ts (modified, +93/-0)
  • extensions/codex/src/app-server/run-attempt.ts (modified, +27/-15)
  • src/agents/command/cli-compaction.test.ts (modified, +85/-0)
  • src/agents/command/cli-compaction.ts (modified, +26/-10)
  • src/agents/pi-embedded-runner.compaction-safety-timeout.test.ts (modified, +128/-0)
  • src/agents/pi-embedded-runner/compact.hooks.harness.ts (modified, +23/-5)
  • src/agents/pi-embedded-runner/compact.hooks.test.ts (modified, +27/-0)
  • src/agents/pi-embedded-runner/compact.queued.ts (modified, +39/-11)
  • src/agents/pi-embedded-runner/compaction-safety-timeout.ts (modified, +84/-3)
  • src/agents/pi-embedded-runner/run.overflow-compaction.test.ts (modified, +20/-0)
  • src/agents/pi-embedded-runner/run.ts (modified, +45/-21)
  • src/context-engine/types.ts (modified, +12/-0)
  • src/plugin-sdk/agent-harness-runtime.ts (modified, +9/-0)

PR #84153: fix(plugins): add default timeout for before_compaction/after_compaction hooks

Description (problem / solution / changelog)

Bug

DEFAULT_VOID_HOOK_TIMEOUT_MS_BY_HOOK in src/plugins/hooks.ts listed only agent_end. The before_compaction and after_compaction plugin hooks are void hooks (runBeforeCompaction / runAfterCompactionrunVoidHook(...)), and runVoidHook applies a timeout only when getVoidHookTimeoutMs returns a value. With no table entry and no plugin-supplied hook.timeoutMs, both hooks ran fully unbounded.

In the codex agent harness these hooks fire on the serialized notification queue — extensions/codex/src/app-server/event-projector.ts handleItemStarted awaits runAgentHarnessBeforeCompactionHook (and the matching after_compaction call site) for a contextCompaction item. A slow or hung compaction hook therefore freezes processing of every later codex notification — including turn/completed — so the whole agent turn hangs.

Fix

Add before_compaction and after_compaction entries to DEFAULT_VOID_HOOK_TIMEOUT_MS_BY_HOOK, mirroring the defensive-default pattern already applied to agent_end. The budget is 30s, matching agent_end (the closest like-for-like precedent — a void lifecycle hook) rather than the tighter 15s modifying-hook defaults, because compaction hooks can legitimately do real work such as a memory flush. The runner is fail-open for void hooks, so a timed-out handler is logged and compaction proceeds without it.

A plugin can still override the default per-registration via hook.timeoutMs.

Related

Related to #84077 — the same compaction-stall investigation. That issue covers the host's missing safety timeout on plugin-owned compact(); this is a separate, independent mechanism (unbounded void hooks freezing the codex notification queue), hence "Related" rather than "Fixes".

Test plan

  • pnpm tsgo:core and pnpm tsgo:core:test — typecheck passes
  • oxlint on changed files — 0 warnings / 0 errors
  • New src/plugins/hooks.compaction-timeout.test.ts:
    • a never-settling before_compaction handler is bounded by the default timeout (no override) and logged, rather than hanging
    • same for after_compaction
    • a fast before_compaction handler completes without a false-positive timeout
  • vitest (plugins project): new tests + hooks.correlation.test.ts + wired-hooks-compaction.test.ts — 15/15 pass

Real behavior proof

Behavior addressed: hung plugin before_compaction and after_compaction handlers no longer stall compaction forever. The hook runner now applies the default fail-open timeout when no per-hook override is configured.

Real environment tested: local OpenClaw checkout /Volumes/LEXAR/repos/openclaw-fix-compaction-hook-timeout, branch fix/compaction-hook-default-timeout, Node via node --import tsx, actual src/plugins/hooks.ts plugin hook runner.

Exact steps or command run after the patch: ran a live script that registers a plugin whose before_compaction and after_compaction hooks never settle, then invokes runHookTimeout for both hooks without per-hook timeout overrides.

Evidence after fix:

{
  "branch": "fix/compaction-hook-default-timeout",
  "behavior": "hung before_compaction and after_compaction hooks return via default fail-open timeout",
  "elapsedMs": 30033,
  "eventCount": 2,
  "events": [
    "[hooks] before_compaction handler from live-proof-plugin failed: timed out after 30000ms",
    "[hooks] after_compaction handler from live-proof-plugin failed: timed out after 30000ms"
  ]
}

Observed result after fix: both hung hook handlers returned through the default timeout path in about 30 seconds each, emitted fail-open timeout events, and did not block the caller indefinitely.

What was not tested: a real external plugin process wedged in production; the proof uses the in-process hook runner with intentionally never-settling handlers.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/plugins/hooks.compaction-timeout.test.ts (added, +121/-0)
  • src/plugins/hooks.ts (modified, +12/-0)

PR #356: Scout: Critical Inherited Defect Report - 2024-05-19

Description (problem / solution / changelog)

🦅 Scout: Critical Inherited Defect Report - 2024-05-19

  • Upstream Issue #84077: Plugin-owned context engines run compaction with no safety timeout
  • Location in our code:
    • src/agents/pi-embedded-runner/compact.ts line 942
    • src/agents/pi-embedded-runner/run.ts line 1030
  • Observed Behavior: When a context engine plugin that owns compaction is asked to compact the session, OpenClaw awaits the contextEngine.compact() call without any timeout, watchdog, or abort signal. If the plugin's compaction process hangs (e.g., due to rate limits or infinite loops), the agent turn stalls indefinitely because the 900s safety timeout is only applied to native compaction.
  • Expected Behavior: The contextEngine.compact() call must be wrapped in a safety timeout (e.g., using compactWithSafetyTimeout or compactContextEngineWithSafetyTimeout) across all call sites to ensure the agent turn can recover or fail cleanly if the plugin engine hangs.

PR created automatically by Jules for task 9358273685489953605 started by @MillionthOdin16

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

Summary by CodeRabbit

  • Documentation
    • Documented a known issue where certain operations could hang without proper safety controls, potentially affecting agent responsiveness. Mitigation recommendations included.
<!-- review_stack_entry_start -->

Review Change Stack

<!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai -->

Changed files

  • .jules/scout.md (added, +4/-0)

Code Example

flowchart TD
    subgraph PE["pi-embedded runner"]
        L1["compact.queued.ts<br/>queued /compact"]
        L2["run.ts<br/>context-overflow recovery"]
        L3["run.ts<br/>run-timeout recovery"]
    end
    subgraph CX["codex agent harness"]
        L4["compact.ts<br/>compactOwningContextEngine"]
        L5["run-attempt.ts<br/>forceContextEngineCompactionForCodexOverflow"]
    end
    L1 --> CE
    L2 --> CE
    L3 --> CE
    L4 --> CE
    L5 --> CE
    CE["await contextEngine.compact()"]
    CE --> X["BEFORE FIX: no timeout / no abort / no watchdog<br/>a hung plugin compact() is awaited forever"]
    NAT["native pi-agent-core compaction"] --> NT["compactWithSafetyTimeout — 900 s bound"]
    NT --> NOTE["the 5 plugin lanes above never received this wrapper"]
    classDef bad fill:#ffe3e3,stroke:#d00000
    classDef good fill:#e3ffe3,stroke:#1a7f1a
    class CE,X bad
    class NT,NOTE good

---

sequenceDiagram
    participant U as User
    participant H as OpenClaw host
    participant E as plugin compact
    participant P as Summarizer provider
    U->>H: message (new turn)
    H->>E: await contextEngine.compact()
    E->>P: summarizer call
    P--xE: rate-limited / unreachable
    E->>P: retry / fallback provider
    P--xE: still failing
    Note over E: minutes of retries and per-call timeouts
    Note over H: no safety timeout — awaits indefinitely
    Note over U: agent is unresponsive

---

flowchart LR
    NQ["codex notification queue<br/>(strictly serialized)"]
    NQ --> E1["item/started: contextCompaction"]
    E1 --> BC["await before_compaction hook"]
    BC --> HUNG["hook hangs — no default timeout"]
    HUNG --> BLOCK["notification queue frozen"]
    BLOCK --> TC["turn/completed never processed"]
    TC --> HANG["the whole agent turn hangs"]
    classDef bad fill:#ffe3e3,stroke:#d00000
    class HUNG,BLOCK,TC,HANG bad
RAW_BUFFERClick to expand / collapse

Filed early as a focused report; expanded with the full investigation — all five call sites, the native-vs-plugin asymmetry, the related compaction-hook gap, diagrams, and the fix mapping.

Summary

When a plugin-owned context engine — one that advertises ownsCompaction: true (e.g. the lossless-claw / LCM plugin) — handles compaction, OpenClaw awaits the engine's ContextEngine.compact() with no timeout, no watchdog, and no abort signal, across five distinct call sites. The 900 s safety timeout (compactWithSafetyTimeout / EMBEDDED_COMPACTION_TIMEOUT_MS) that protects native pi-agent-core compaction was never applied to the plugin-owned lanes.

If a plugin engine's compact() is slow or hangs, the agent turn is unresponsive for the entire duration. The only backstop is the default 48-hour agent run timeout — and even that cannot interrupt the plugin call, because ContextEngine.compact() has no abortSignal in its contract.

User-visible symptom: "the agent stopped responding right after it started compacting."

A second, independent host-side gap in the same area — unbounded before_compaction / after_compaction hooks — is documented under Related host-side gap below.

The compaction-stall surface

flowchart TD
    subgraph PE["pi-embedded runner"]
        L1["compact.queued.ts<br/>queued /compact"]
        L2["run.ts<br/>context-overflow recovery"]
        L3["run.ts<br/>run-timeout recovery"]
    end
    subgraph CX["codex agent harness"]
        L4["compact.ts<br/>compactOwningContextEngine"]
        L5["run-attempt.ts<br/>forceContextEngineCompactionForCodexOverflow"]
    end
    L1 --> CE
    L2 --> CE
    L3 --> CE
    L4 --> CE
    L5 --> CE
    CE["await contextEngine.compact()"]
    CE --> X["BEFORE FIX: no timeout / no abort / no watchdog<br/>a hung plugin compact() is awaited forever"]
    NAT["native pi-agent-core compaction"] --> NT["compactWithSafetyTimeout — 900 s bound"]
    NT --> NOTE["the 5 plugin lanes above never received this wrapper"]
    classDef bad fill:#ffe3e3,stroke:#d00000
    classDef good fill:#e3ffe3,stroke:#1a7f1a
    class CE,X bad
    class NT,NOTE good

The five ownsCompaction compact() call sites

#LaneFile / functionTrigger
1queued /compactsrc/agents/pi-embedded-runner/compact.queued.tsmanual /compact
2overflow recoverysrc/agents/pi-embedded-runner/run.tscontext-overflow / force-on-max-token
3timeout recoverysrc/agents/pi-embedded-runner/run.tsrun-timeout recovery
4codex owned compactionextensions/codex/src/app-server/compact.tscompactOwningContextEnginecodex budget / manual compaction
5codex overflowextensions/codex/src/app-server/run-attempt.tsforceContextEngineCompactionForCodexOverflowcodex turn overflow

Sites 1–3 are the pi-embedded runner. Sites 4–5 are the codex agent harnesscompact.queued.ts early-returns to maybeCompactCodexAppServerSession before its own lane-queued compact() is reached, so for a codex-harness agent with an ownsCompaction plugin (the common production setup) sites 4–5 are the lanes that actually run.

Each site has a try/catch that converts a thrown compact() error into a clean { ok: false } result — but a hang (a promise that never settles) is not a throw, so the catch does nothing for it.

Root cause

compactWithSafetyTimeout (src/agents/pi-embedded-runner/compaction-safety-timeout.ts, EMBEDDED_COMPACTION_TIMEOUT_MS = 900_000) does exist and is applied — but only around the native activeSession.compact() call inside compactEmbeddedPiSessionDirectOnce. A plugin engine that owns compaction bypasses delegateCompactionToRuntime and therefore never reaches that wrapper.

Verified: the installed 2026.5.18 dist chunk containing the contextEngine.compact() call sites has zero references to compactWithSafetyTimeout.

Aggravators:

  • ContextEngine.compact() (src/context-engine/types.ts) has no abortSignal parameter. A run-level abort (abortRunactiveSession.abortCompaction()) only aborts the native session — a plugin compact() in flight receives no cancellation.
  • waitForCompactionRetryWithAggregateTimeout re-arms indefinitely while isCompactionStillInFlight() is true, so its 60 s aggregate timeout degrades to an infinite wait if a compaction_start is never matched by a compaction_end.

The stall

sequenceDiagram
    participant U as User
    participant H as OpenClaw host
    participant E as plugin compact
    participant P as Summarizer provider
    U->>H: message (new turn)
    H->>E: await contextEngine.compact()
    E->>P: summarizer call
    P--xE: rate-limited / unreachable
    E->>P: retry / fallback provider
    P--xE: still failing
    Note over E: minutes of retries and per-call timeouts
    Note over H: no safety timeout — awaits indefinitely
    Note over U: agent is unresponsive

The plugin-side reasons a compact() can run this long (unbounded sweep loops, a rate-limited summarizer) are tracked at Martian-Engineering/lossless-claw#711. This issue is the host-side half: regardless of why a plugin compact() is slow, OpenClaw must not await it unbounded.

Related host-side gap: compaction hooks

A second, independent host-side gap sits in the same area. The before_compaction and after_compaction plugin hooks have no default timeout: DEFAULT_VOID_HOOK_TIMEOUT_MS_BY_HOOK (src/plugins/hooks.ts) lists only agent_end, and runVoidHook applies a timeout only when one is resolved — so with no table entry and no plugin-supplied hook.timeoutMs, these hooks run fully unbounded.

In the codex agent harness these hooks fire on the strictly serialized notification queue:

flowchart LR
    NQ["codex notification queue<br/>(strictly serialized)"]
    NQ --> E1["item/started: contextCompaction"]
    E1 --> BC["await before_compaction hook"]
    BC --> HUNG["hook hangs — no default timeout"]
    HUNG --> BLOCK["notification queue frozen"]
    BLOCK --> TC["turn/completed never processed"]
    TC --> HANG["the whole agent turn hangs"]
    classDef bad fill:#ffe3e3,stroke:#d00000
    class HUNG,BLOCK,TC,HANG bad

Environment

  • OpenClaw 2026.5.18 (traced in the installed npm dist; the structure is present across 2026.5.x).
  • A plugin context engine with ownsCompaction: true installed (reproduced with lossless-claw / LCM).

Reproduction

  1. Install a context-engine plugin that sets ownsCompaction: true (e.g. lossless-claw).
  2. Configure its summarizer to a model/provider that is slow or rate-limited.
  3. Drive a long session past the compaction threshold, or hit max-token overflow to force compaction.
  4. The plugin's compact() runs slowly; the host awaits it with no timeout; the agent turn never returns.

Expected vs actual

  • Expected: plugin-owned compaction is bounded by the same safety timeout as native compaction; on timeout the host fails the compaction cleanly (surfacing an error and/or falling back) instead of hanging the turn.
  • Actual: no timeout on any of the five plugin lanes; the turn hangs until the 48 h run timeout, which itself cannot abort the plugin call.

Fix

  • compact() no-timeout (this issue): PR openclaw/openclaw#84083 — adds a compactContextEngineWithSafetyTimeout helper and wraps all five ownsCompaction compact() call sites; adds an optional abortSignal to the ContextEngine.compact() contract and threads the run abort signal through. The helper is shared with the codex extension via the openclaw/plugin-sdk/agent-harness-runtime surface (one implementation, no copy-paste).
  • Compaction-hook no-timeout (the related gap): PR openclaw/openclaw#84153 — adds before_compaction / after_compaction default entries (30 s) to DEFAULT_VOID_HOOK_TIMEOUT_MS_BY_HOOK.

Related

  • #83765 — Telegram DM stalls behind embedded auto-compaction session — likely a user-facing symptom of this.
  • #64962 — Timeout-compaction doesn't escalate when compaction fails to reduce context.
  • #70334 — Session lock stuck in 'processing' after context overflow compaction succeeds.
  • #81182 — Overflow recovery should truncate tool results before waiting full auto-compaction timeout.
  • #81164 — the in-flight interceptCompaction work wires an abort-aware path for the separate codex session_before_compact intercept lane (the interceptsCompaction capability). This issue concerns the ownsCompaction queued/overflow/timeout lanes, which that work does not cover.
  • Martian-Engineering/lossless-claw#711 — the LCM-side half (unbounded compactFullSweep / compactUntilUnder).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING