openclaw - 💡(How to fix) Fix [Bug]: [Bug]: ContextEngine afterTurn declares isHeartbeat but does not forward it [3 pull requests]

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…

OpenClaw 2026.5.12 declares ContextEngine.afterTurn(params).isHeartbeat?: boolean, but observed afterTurn call sites do not pass isHeartbeat to context-engine plugins.

Root Cause

{ "status": "ok-token", "reason": "wake", "silent": true } The context-engine plugin stored heartbeat-related messages because no top-level isHeartbeat signal was observed by the plugin.

Fix Action

Fixed

Code Example

SDK type evidence:

`dist/plugin-sdk/src/context-engine/types.d.ts:215`


/** True when this turn belongs to a heartbeat run. */
isHeartbeat?: boolean;

Runtime call site 1:

dist/selection-61FIEezO.js:4793

await contextEngine.afterTurn({
  sessionId,
  sessionKey,
  sessionFile,
  messages: sourceMessages,
  prePromptMessageCount,
  tokenBudget,
  runtimeContext: params.getRuntimeContext?.(...)
});
Runtime call site 2:

dist/attempt.tool-run-context-BuKiw0o1.js:474

await params.contextEngine.afterTurn({
  sessionId: params.sessionIdUsed,
  sessionKey: params.sessionKey,
  sessionFile: params.sessionFile,
  messages: conversationSnapshot.messages,
  prePromptMessageCount: conversationSnapshot.prePromptMessageCount,
  tokenBudget: params.tokenBudget,
  runtimeContext: params.runtimeContext
});
E2E heartbeat wake evidence:

openclaw system event --mode now --expect-final --text "..." produced a heartbeat result:

{
  "status": "ok-token",
  "reason": "wake",
  "silent": true
}
The context-engine plugin stored heartbeat-related messages because no top-level isHeartbeat signal was observed by the plugin.


**Impact and severity**

Affected: Context-engine plugins that rely on `afterTurn(params).isHeartbeat` to skip heartbeat turns.
Severity: Data risk / memory pollution.
Frequency: Observed on OpenClaw 2026.5.12 afterTurn heartbeat wake path.
Consequence: Plugins cannot reliably distinguish heartbeat turns from normal turns via the documented top-level afterTurn field.
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

OpenClaw 2026.5.12 declares ContextEngine.afterTurn(params).isHeartbeat?: boolean, but observed afterTurn call sites do not pass isHeartbeat to context-engine plugins.

Steps to reproduce

  1. Start OpenClaw 2026.5.12 with a context-engine plugin enabled.
  2. Inspect the SDK type at dist/plugin-sdk/src/context-engine/types.d.ts.
  3. Inspect the runtime afterTurn call sites in dist/selection-61FIEezO.js and dist/attempt.tool-run-context-BuKiw0o1.js.
  4. Trigger a real heartbeat wake with openclaw system event --mode now --expect-final --text "test".
  5. Observe that the context-engine afterTurn call receives no top-level isHeartbeat field.

Expected behavior

For heartbeat runs, OpenClaw should pass isHeartbeat: true to contextEngine.afterTurn(...), matching the SDK type declaration.

Actual behavior

The SDK type declares isHeartbeat?: boolean, but the observed 2026.5.12 afterTurn call objects only pass sessionId, sessionKey, sessionFile, messages, prePromptMessageCount, tokenBudget, and runtimeContext.

Observed call sites:

  • dist/selection-61FIEezO.js:4793
  • dist/attempt.tool-run-context-BuKiw0o1.js:474

OpenClaw version

2026.5.12

Operating system

Windows 10.0.26200 x64

Install method

Local node_modules CLI, launched with openclaw.cmd gateway run

Model

doubao-seed-2.0-code

Provider / routing chain

NOT_ENOUGH_INFO

Additional provider/model setup details

NOT_ENOUGH_INFO

Logs, screenshots, and evidence

SDK type evidence:

`dist/plugin-sdk/src/context-engine/types.d.ts:215`


/** True when this turn belongs to a heartbeat run. */
isHeartbeat?: boolean;

Runtime call site 1:

dist/selection-61FIEezO.js:4793

await contextEngine.afterTurn({
  sessionId,
  sessionKey,
  sessionFile,
  messages: sourceMessages,
  prePromptMessageCount,
  tokenBudget,
  runtimeContext: params.getRuntimeContext?.(...)
});
Runtime call site 2:

dist/attempt.tool-run-context-BuKiw0o1.js:474

await params.contextEngine.afterTurn({
  sessionId: params.sessionIdUsed,
  sessionKey: params.sessionKey,
  sessionFile: params.sessionFile,
  messages: conversationSnapshot.messages,
  prePromptMessageCount: conversationSnapshot.prePromptMessageCount,
  tokenBudget: params.tokenBudget,
  runtimeContext: params.runtimeContext
});
E2E heartbeat wake evidence:

openclaw system event --mode now --expect-final --text "..." produced a heartbeat result:

{
  "status": "ok-token",
  "reason": "wake",
  "silent": true
}
The context-engine plugin stored heartbeat-related messages because no top-level isHeartbeat signal was observed by the plugin.


**Impact and severity**

Affected: Context-engine plugins that rely on `afterTurn(params).isHeartbeat` to skip heartbeat turns.
Severity: Data risk / memory pollution.
Frequency: Observed on OpenClaw 2026.5.12 afterTurn heartbeat wake path.
Consequence: Plugins cannot reliably distinguish heartbeat turns from normal turns via the documented top-level afterTurn field.

Impact and severity

No response

Additional information

The issue was observed with OpenViking as the active context-engine plugin. OpenViking has defensive code that checks afterTurnParams.isHeartbeat, but the field was not present in the observed 2026.5.12 afterTurn call path.

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…

FAQ

Expected behavior

For heartbeat runs, OpenClaw should pass isHeartbeat: true to contextEngine.afterTurn(...), matching the SDK type declaration.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING