openclaw - ✅(Solved) Fix [Bug]: runtime-deps manifest still missing 9 dist bare-imports in 2026.4.26 (follow-up to #71420) [4 pull requests, 5 comments, 6 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#74199Fetched 2026-04-30 06:27:31
View on GitHub
Comments
5
Participants
6
Timeline
17
Reactions
2
Author
Timeline (top)
cross-referenced ×8commented ×5referenced ×3closed ×1

The runtime-deps mirror manifest at ~/.openclaw/plugin-runtime-deps/openclaw-<version>/.openclaw-runtime-deps.json is missing 9 packages that the dist code does import x from 'pkg' for. They never get installed into the mirror, so when a dist code path that imports them is exercised, Node fails resolution: Cannot find package 'X' imported from ~/.openclaw/plugin-runtime-deps/openclaw-.../dist/....

This is a follow-up to #71420 — that fix shipped (and 2026.4.26 added chokidar to the manifest, fixing the qmd-manager symptom we hit), but the manifest still does not match the actual set of bare-imports in dist.

Error Message

The 9 above will surface the same error class when their code paths run.

Root Cause

Affected: any user on 2026.4.26 (and likely earlier) whose plugin/code path exercises one of the 9 imports (e.g. cron scheduling → croner, push notifications → web-push, archive/backup → tar, dotenv-driven config → dotenv). Severity: variable — module-not-found at first reach; in our case it cascaded into a gateway restart loop because the failing module was on the qmd-memory startup path. Frequency: every fresh install / version upgrade until the manifest catches up. Consequence: feature failure or, for hot-path imports, gateway-level outage.

Fix Action

Fix / Workaround

Manual workaround that resolved the live incident (replicate per missing package):

PR fix notes

PR #74213: fix(plugins): mirror core root-package deps used by core dist code

Description (problem / solution / changelog)

Summary

Extend `MIRRORED_CORE_RUNTIME_DEP_NAMES` (in `src/plugins/bundled-runtime-deps.ts`) to include the nine root-package runtime dependencies that core dist code imports but that the current allowlist does not mirror into the runtime-deps tree:

  • `@agentclientprotocol/sdk`
  • `croner`
  • `dotenv`
  • `jiti`
  • `json5`
  • `jszip`
  • `markdown-it`
  • `tar`
  • `web-push`

Context

Currently `MIRRORED_CORE_RUNTIME_DEP_NAMES` is just `["semver", "tslog"]`. The dynamic `collectRootDistMirroredRuntimeDeps` scan picks up other imports only when an enabled extension's `package.json` declares the dependency (so `chokidar` works in 2026.4.26 because `extensions/memory-core/package.json` declares it; `jiti` and `markdown-it` work when `matrix` is enabled because `extensions/matrix/package.json` declares them).

But these nine packages are imported by core dist code, not by an extension:

PackageImported by (representative)
`@agentclientprotocol/sdk``src/acp/event-mapper.ts`, `src/acp/client-helpers.ts`
`croner``src/cron/schedule.ts`
`dotenv``src/config/state-dir-dotenv.ts`, `src/infra/dotenv.ts`
`jiti``src/plugin-sdk/root-alias.cjs`, `src/plugins/jiti-loader-cache.ts`
`json5``src/utils/parse-json-compat.ts`, `src/shared/frontmatter.ts`
`jszip``src/infra/archive.ts`, `src/plugins/clawhub.ts`
`markdown-it``src/markdown/ir.ts`
`tar``src/commands/backup-verify.ts`
`web-push``src/infra/push-web.ts`

For setups where no enabled extension owns the dependency, the imports never get installed into `~/.openclaw/plugin-runtime-deps/openclaw-<ver>/node_modules`, and Node fails to resolve them when the corresponding code path runs:

``` Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/qmd-manager-FuXCtSYP.js ```

(That specific case was fixed in 2026.4.26 because `memory-core` started declaring `chokidar`. The nine above behave the same way.)

Reproduction

Against a vanilla `npm i -g [email protected]`:

```bash cd ~/.npm-global/lib/node_modules/openclaw/dist grep -rh '^import .* from "[^./n]' *.js | grep -oE 'from "[^"]+"' | sort -u

compare each top-level package against .specs[] of:

~/.openclaw/plugin-runtime-deps/openclaw-<ver>/.openclaw-runtime-deps.json

```

The nine listed above appear in dist imports but are not in the manifest `specs`.

Approach

These deps fit the same pattern as the existing `semver` / `tslog` entries: declared in the openclaw root `package.json` and used by core dist code. Adding them to `MIRRORED_CORE_RUNTIME_DEP_NAMES` is the smallest, most consistent fix.

A more durable fix would derive the list from a static analysis of core dist bare-imports during build (or extend `collectRootDistMirroredRuntimeDeps` to treat root `package.json` as a fallback owner) so the allowlist cannot drift as new core deps are added. I left that as a follow-up to keep this PR mechanical and easy to review.

Refs

  • Issue: #74199
  • Adjacent / closed: #71420 (original locked thread covering the same class of bug; this PR addresses the gap between `MIRRORED_CORE_RUNTIME_DEP_NAMES` and the actual import set)

Test plan

  • `pnpm test src/plugins/bundled-runtime-deps.test.ts` — 87 passed
  • `pnpm test src/plugins/stage-bundled-plugin-runtime-deps.test.ts src/commands/doctor-bundled-plugin-runtime-deps.test.ts src/infra/package-dist-inventory.test.ts` — all passed
  • `pnpm format:check src/plugins/bundled-runtime-deps.ts CHANGELOG.md` — clean
  • Verify against a fresh install: install on a host without any of the nine packages currently in the mirror, then trigger code paths (e.g. `openclaw cron list`, push notification path, backup) and confirm no `Cannot find package` errors.

🤖 Generated with Claude Code

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/plugins/bundled-runtime-deps.test.ts (modified, +222/-0)
  • src/plugins/bundled-runtime-deps.ts (modified, +14/-1)

PR #74335: fix(codex/app-server): bound startup timeout independently of per-turn timeout

Description (problem / solution / changelog)

Summary

  • Problem: withCodexStartupTimeout reuses params.timeoutMs (the per-turn budget, often 30 minutes) as the startup ceiling. A deterministic local startup failure — for example a partially extracted plugin-runtime-deps mirror missing a dist/errors-*.js chunk — holds the agent lane for the full turn budget before timing out.
  • Why it matters: Observed at durationMs=1799434 on operator gateways with 30-minute turn timeouts, recurring every ~30 minutes overnight and starving every agent of a working model. One bad runtime-deps extraction becomes a 30-minute outage instead of a fail-fast 2-minute restart.
  • What changed: Add appServer.startupTimeoutMs (default 120000ms) to CodexPluginConfig and CodexAppServerRuntimeOptions, expose options.startupTimeoutMs on runCodexAppServerAttempt, and use it in place of params.timeoutMs for withCodexStartupTimeout.
  • What did NOT change: Per-turn timeoutMs semantics for the actual turn (post-startup) are untouched. requestTimeoutMs for control-plane requests is untouched. The existing startupTimeoutFloorMs floor remains.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Gateway / orchestration
  • API / contracts (additive only — new optional config + manifest entry)

Linked Issue/PR

  • Related #73520 (stale plugin-runtime-deps causes Gateway crash-loop after openclaw update — In Progress; this PR makes the symptom recover quickly even when the underlying extraction issue is not yet fixed)
  • Related #74199 (runtime-deps manifest still missing dist bare-imports; PR #74213 merged but v2026.4.26 npm-global still reproduced for our reporter — separate fresh repro to be filed)
  • Related #73805 (prewarmConfiguredPrimaryModel blocks 30s on startup — same family of "startup hides behind a wall-clock timeout" bug, but distinct: that one is 30s on prewarm, this one is up to per-turn budget on app-server start)
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: runCodexAppServerAttempt did not have an independent startup timeout. The single withCodexStartupTimeout({ timeoutMs: params.timeoutMs, … }) call (run-attempt.ts:309) reused the per-turn budget for the startup phase. With operator-typical 30-minute turn timeouts, a startup failure (ENOENT on a runtime-deps dist/errors-*.js chunk after a bad upgrade extraction) sat there for ~30 minutes before bubbling out as codex app-server startup aborted.
  • Missing detection / guardrail: Codex local startup failures (ENOENT, module-resolution) are deterministic and immediately knowable; the wall-clock timeout was the only escape, and it was set far too long. There was no separate startup ceiling, and the alignment test did not flag a missing knob because no knob existed.
  • Contributing context: This compounded with #73520 and #74199 (incomplete plugin-runtime-deps extraction on upgrade) — those bugs created the failure, this bug amplified one occurrence into a 30-minute outage.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this: Unit test asserting that startup timing is bounded independently of params.timeoutMs.
  • New tests added:
    • extensions/codex/src/app-server/config.test.ts: resolver default (120000ms) and configured override (5000ms) are honored.
    • extensions/codex/src/app-server/run-attempt.test.ts: existing times out app-server startup before thread setup can hang forever test updated to use startupTimeoutMs instead of relying on small params.timeoutMs. New test uses startup timeout independent of per-turn timeout (regression: 30-min hang) sets params.timeoutMs = 30 * 60_000 and asserts startup rejects in <5s when startupTimeoutMs: 1 is supplied.

Architecture / Flow Diagram

Before:
runCodexAppServerAttempt({ timeoutMs: T_turn })
  └─ withCodexStartupTimeout({ timeoutMs: T_turn })  ← startup hidden behind whole-turn budget
        └─ on local ENOENT → pending until T_turn elapses → "codex app-server startup aborted"

After:
runCodexAppServerAttempt({ timeoutMs: T_turn })
  └─ resolveCodexAppServerRuntimeOptions(...) → { startupTimeoutMs: T_startup, ... }   (default 120000)
  └─ withCodexStartupTimeout({ timeoutMs: T_startup })   ← independent ceiling
        └─ on local ENOENT → fail fast at T_startup → "codex app-server startup timed out"

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS 25.3.0 (darwin)
  • Runtime/container: npm-global install of [email protected]
  • Model/provider: openai-codex/gpt-5.5 (configured primary)
  • Integration/channel (if any): N/A — gateway-internal failure
  • Relevant config (redacted): agents.defaults.model.primary = "openai-codex/gpt-5.5"; tools.exec.security = "full"

Steps

  1. Upgrade from v2026.4.25 → v2026.4.26 with openclaw update while the install ends up with an incomplete ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.26-<hash>/dist/ extraction (errors-mgRbu9kw.js missing, observed in our case).
  2. Allow agents to attempt turns overnight via cron / heartbeat / channels.
  3. Observe gateway.err.log for repeated [agents/harness] Codex agent harness failed; not falling back to embedded PI backend followed by lane task error: durationMs≈1800000 error="Error: codex app-server startup aborted" every ~30 minutes.

Expected

  • Codex app-server startup failure surfaces within 60–120s with the missing-module error path so the gateway can either retry, repair, or fall back without holding the lane.

Actual (before this PR)

  • Lane held for the full per-turn timeout (~30 min) before reporting "startup aborted." Recurring every ~30 minutes from 03:20 to 06:11 local on the night the issue was reported. Agents had tool_calls=0 for the entire window.

Evidence

  • Failing trace before (extracted from operator's gateway.err.log):
    2026-04-29T03:50:40.640-05:00 [agents/harness] Codex agent harness failed; not falling back to embedded PI backend
    2026-04-29T03:50:40.641-05:00 [diagnostic] lane task error: lane=main durationMs=1785599 error="Error: codex app-server startup aborted"
    2026-04-29T05:40:44.785-05:00 [diagnostic] lane task error: lane=main durationMs=1799434 error="Error: codex app-server startup aborted"
    2026-04-29T06:41:32.452-05:00 [plugins] plugin service failed (browser-control, plugin=browser): Cannot find module '~/.openclaw/plugin-runtime-deps/openclaw-2026.4.26-edd222f781b2/dist/errors-mgRbu9kw.js'
  • Passing test after:
    • pnpm test extensions/codex/src/app-server/run-attempt.test.ts -t startup → 4/4 startup tests pass.
    • pnpm test extensions/codex/src/app-server/config.test.ts -t startupTimeoutMs → resolver default+override pass.
    • Full files: pnpm test extensions/codex/src/app-server/run-attempt.test.ts extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/schema-normalization-runtime-contract.test.ts → 54/54 pass.

Human Verification (required)

  • Verified scenarios:
    • Resolver default (startupTimeoutMs = 120000) and explicit configured value (5000) both honored.
    • options.startupTimeoutMs override on runCodexAppServerAttempt takes precedence over resolved config (test: times out app-server startup before thread setup can hang forever).
    • Startup timeout independent of per-turn timeout: params.timeoutMs = 30 * 60_000 does not extend startup ceiling (regression test).
    • pnpm tsgo:extensions clean, pnpm exec oxfmt --check --threads=1 clean on all 8 modified files, manifest alignment test (which compares CODEX_APP_SERVER_CONFIG_KEYS against manifest schema keys and uiHints) still passes after adding startupTimeoutMs to all three.
  • Edge cases checked:
    • Existing startupTimeoutFloorMs floor still applies (no behavior change to the floor; Math.max(floor ?? 100, timeoutMs) is unchanged).
    • Three test fixtures that construct CodexAppServerRuntimeOptions directly (not through the resolver) updated with startupTimeoutMs: 120_000 so typecheck stays clean.
  • What I did NOT verify:
    • Did not run pnpm check (full prod sweep) or pnpm test (full suite) locally — relied on targeted test files plus extensions typecheck. Maintainers may want CI to run the full gate.

Compatibility / Migration

  • Backward compatible? Yes — the new field is optional in CodexPluginConfig; runtime resolver provides a sane default of 120000ms, so existing installs see no behavior change unless they hit a startup failure that previously hung for a long time (in which case they now fail in 2 minutes instead of up to 30+).
  • Config/env changes? Yes (additive) — new optional plugins.entries.codex.config.appServer.startupTimeoutMs.
  • Migration needed? No.

Risks and Mitigations

  • Risk: 120000ms (2 min) is too tight for users on a very slow first-time managed Codex download.
    • Mitigation: The value is configurable via appServer.startupTimeoutMs. The previous behavior (effectively unbounded for the turn budget) is recoverable by setting startupTimeoutMs to a large value. Default chosen because Codex CLI binary is bundled by the runtime-deps mirror, so cold-start should not normally include a download — the situation that motivated this PR.
  • Risk: Adding a required field to CodexAppServerRuntimeOptions could break callers constructing the type literally.
    • Mitigation: Repo grep shows production code routes through resolveCodexAppServerRuntimeOptions. The three test fixtures that did construct literals are updated in this PR.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/plugins/codex-harness.md (modified, +16/-15)
  • extensions/codex/openclaw.plugin.json (modified, +10/-0)
  • extensions/codex/src/app-server/config.test.ts (modified, +15/-0)
  • extensions/codex/src/app-server/config.ts (modified, +5/-0)
  • extensions/codex/src/app-server/run-attempt.test.ts (modified, +21/-4)
  • extensions/codex/src/app-server/run-attempt.ts (modified, +2/-1)
  • extensions/codex/src/app-server/schema-normalization-runtime-contract.test.ts (modified, +1/-0)

PR #74442: fix(gateway): persist hidden lifecycle session keys

Description (problem / solution / changelog)

Summary

  • Problem: hidden channel-routed runs could drop sessionKey on lifecycle events before gateway listeners handled them.
  • Why it matters: when the terminal lifecycle event lost its session key, gateway session persistence could miss the final status write and leave the session stuck as running.
  • What changed: emitAgentEvent() now preserves sessionKey for hidden lifecycle events only, and adds focused regression coverage for hidden lifecycle versus hidden assistant events.
  • What did NOT change (scope boundary): hidden assistant/tool traffic is still redacted from Control UI event payloads; no channel-routing, transcript, or session-store schema changes were made.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #74335
  • Related #74341
  • Related #74199
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: hidden channel runs (isControlUiVisible: false) stripped sessionKey from all agent events at the shared event bus boundary, including terminal lifecycle events that gateway listeners use to persist session status.
  • Missing detection / guardrail: existing tests covered hidden-session chat suppression and visible lifecycle persistence separately, but not the hidden lifecycle event path itself.
  • Contributing context (if known): gateway lifecycle persistence in server-chat.ts can recover sessionKey from run context or lookup helpers, but that recovery is weaker than carrying the explicit session key through the lifecycle event itself.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/infra/agent-events.test.ts
  • Scenario the test should lock in: hidden runs must still redact assistant traffic while preserving sessionKey on lifecycle events so downstream gateway listeners can persist terminal session state.
  • Why this is the smallest reliable guardrail: the bug is caused at the shared event-bus seam before gateway lifecycle persistence runs, so the smallest stable proof is to assert the event payload shape at that seam.
  • Existing test that already covers this (if any): src/gateway/server-chat.agent-events.test.ts already covers hidden-run chat suppression and visible lifecycle persistence separately.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Channel-routed sessions that complete a hidden Codex turn now keep their terminal lifecycle session key, allowing gateway session state to persist out of running instead of getting stranded.

Diagram (if applicable)

Before:
[hidden channel run] -> [lifecycle end event drops sessionKey] -> [gateway lifecycle persistence may miss terminal write]

After:
[hidden channel run] -> [lifecycle end event keeps sessionKey] -> [gateway persists terminal session state]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS (operator repro from Knox's machine)
  • Runtime/container: OpenClaw v2026.4.26
  • Model/provider: Codex app-server via hidden channel-routed sessions
  • Integration/channel (if any): Paperclip issue routing and BlueBubbles direct routing
  • Relevant config (redacted): hidden channel-routed sessions with isControlUiVisible: false

Steps

  1. Run a channel-routed hidden session such as agent:<agent>:paperclip:issue:<uuid> or agent:knox:bluebubbles:default:direct:<phone>.
  2. Let Codex finish the turn so the transcript contains a terminal assistant message (stopReason: "stop").
  3. Inspect the persisted session entry and gateway diagnostics.

Expected

  • The terminal lifecycle event carries enough session identity for gateway listeners to persist a terminal session status and clear the running state.

Actual

  • The operator observed entries left at status: "running" with stuck-session diagnostics such as:
  • 2026-04-29T09:50:34.939-05:00 [diagnostic] stuck session: sessionId=helm-dev sessionKey=agent:helm-dev:paperclip:issue:8931a100-c86e-4a92-8f65-b29d813bd4d5 state=processing age=565s queueDepth=0

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: formatted the diff; ran pnpm tsgo:core, pnpm tsgo:extensions, pnpm tsgo:core:test, pnpm tsgo:extensions:test, pnpm test src/infra/agent-events.test.ts, pnpm test src/gateway/server-chat.agent-events.test.ts, pnpm test src/gateway/session-lifecycle-state.test.ts, and pnpm lint:extensions:bundled; ran an external Codex review that returned ship it.
  • Edge cases checked: hidden assistant events still omit sessionKey; visible gateway lifecycle suites still pass unchanged.
  • What you did not verify: a live end-to-end repro against Knox's local gateway install after applying this branch.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: lifecycle events for hidden runs now include sessionKey on the shared agent-event bus.
    • Mitigation: the change is scoped to stream === "lifecycle" only; hidden assistant/tool traffic remains redacted, and existing gateway hidden-run chat suppression tests still pass.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/gateway/server-chat.agent-events.test.ts (modified, +9/-1)
  • src/gateway/server-chat.ts (modified, +6/-4)
  • src/infra/agent-events.test.ts (modified, +44/-1)
  • src/infra/agent-events.ts (modified, +8/-1)

PR #74713: fix(plugins): repair configured provider runtime deps

Description (problem / solution / changelog)

Summary

  • centralize bundled runtime-deps selection so doctor, plugins deps, and startup repair include configured provider owners such as anthropic-vertex without staging inactive provider plugins
  • remove the duplicate doctor-only packaged plugin selector and document the configured channel/provider staging rules
  • atomically refresh materialized root dist chunks in external mirrors so a failed link/copy keeps the previous valid chunk instead of leaving a missing file

Issues

  • Refs #74307
  • Refs #74199

Validation

  • pnpm exec oxfmt --check --threads=1 src/plugins/bundled-runtime-mirror.ts src/plugins/bundled-runtime-root.test.ts src/plugins/bundled-runtime-deps-selection.ts src/plugins/bundled-runtime-deps.test.ts src/commands/doctor-bundled-plugin-runtime-deps.ts src/commands/doctor-bundled-plugin-runtime-deps.test.ts src/plugins/test-helpers/bundled-runtime-deps-fixtures.ts
  • pnpm test src/plugins/bundled-runtime-root.test.ts src/plugins/bundled-runtime-deps.test.ts src/commands/doctor-bundled-plugin-runtime-deps.test.ts src/cli/plugins-deps-command.test.ts
  • pnpm check:changelog-attributions
  • Blacksmith Testbox: OPENCLAW_TESTBOX=1 pnpm check:changed passed before the final rebase; after rebasing onto current main, reran the targeted checks above.

Changed files

  • CHANGELOG.md (modified, +2/-0)
  • docs/cli/plugins.md (modified, +1/-1)
  • docs/gateway/doctor.md (modified, +1/-1)
  • src/commands/doctor-bundled-plugin-runtime-deps.test.ts (modified, +54/-22)
  • src/commands/doctor-bundled-plugin-runtime-deps.ts (modified, +0/-83)
  • src/plugins/bundled-runtime-deps-selection.ts (modified, +91/-1)
  • src/plugins/bundled-runtime-deps.test.ts (modified, +44/-0)
  • src/plugins/bundled-runtime-mirror.ts (modified, +12/-6)
  • src/plugins/bundled-runtime-root.test.ts (modified, +21/-0)
  • src/plugins/test-helpers/bundled-runtime-deps-fixtures.ts (modified, +2/-0)

Code Example

cd ~/.npm-global/lib/node_modules/openclaw/dist
grep -rh '^import .* from "[^./n]' *.js | grep -oE 'from "[^"]+"' | sort -u
# compare each top-level package against .specs[] of:
# ~/.openclaw/plugin-runtime-deps/openclaw-<ver>/.openclaw-runtime-deps.json

---

Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/qmd-manager-FuXCtSYP.js

---

[memory] qmd memory unavailable; falling back to builtin: Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/qmd-manager-FuXCtSYP.js
[gateway] qmd memory startup initialization failed for agent "main": Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/manager-...js

---

cd ~/.openclaw/plugin-runtime-deps/openclaw-<version>
xargs -a /tmp/all-specs.txt npm install --no-save
# where /tmp/all-specs.txt is the manifest specs PLUS the 9 missing packages
# at versions read from the npm-global package.json

---

grep -rh '^import .* from "[^./n]' dist/*.js \
  | grep -oE 'from "[^"]+"' \
  | sed -E 's|from "(@[^/]+/[^/]+).*"|\1|; s|from "([^/"]+).*"|\1|' \
  | sort -u
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

The runtime-deps mirror manifest at ~/.openclaw/plugin-runtime-deps/openclaw-<version>/.openclaw-runtime-deps.json is missing 9 packages that the dist code does import x from 'pkg' for. They never get installed into the mirror, so when a dist code path that imports them is exercised, Node fails resolution: Cannot find package 'X' imported from ~/.openclaw/plugin-runtime-deps/openclaw-.../dist/....

This is a follow-up to #71420 — that fix shipped (and 2026.4.26 added chokidar to the manifest, fixing the qmd-manager symptom we hit), but the manifest still does not match the actual set of bare-imports in dist.

Steps to reproduce

cd ~/.npm-global/lib/node_modules/openclaw/dist
grep -rh '^import .* from "[^./n]' *.js | grep -oE 'from "[^"]+"' | sort -u
# compare each top-level package against .specs[] of:
# ~/.openclaw/plugin-runtime-deps/openclaw-<ver>/.openclaw-runtime-deps.json

On 2026.4.26 the following packages are imported by dist but absent from the manifest:

  • @agentclientprotocol/sdk
  • croner
  • dotenv
  • jiti
  • json5
  • jszip
  • markdown-it
  • tar
  • web-push

All 9 are listed as direct dependencies in the openclaw npm package.json (so they exist at ~/.npm-global/lib/node_modules/openclaw/node_modules/<pkg>), but the mirror tree under ~/.openclaw/plugin-runtime-deps/.../node_modules/ does not get them — Node only walks up from the importing file's location, and the npm-global tree isn't on that path, so resolution fails.

Concrete prior failure (now fixed for chokidar specifically):

Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/qmd-manager-FuXCtSYP.js

The 9 above will surface the same error class when their code paths run.

Expected behavior

Every package the dist code imports as a bare specifier should be present in the mirror, either by being listed in .openclaw-runtime-deps.json (so the runtime installer adds it) or by being installed alongside the manifest specs.

Actual behavior

The manifest is hand-curated and drifts behind dist's actual imports. After updating from 2026.4.25 → 2026.4.26 a fresh 2026.4.26-... mirror dir is created and 9 packages remain absent.

OpenClaw version

2026.4.26 (be8c246)

Operating system

Linux 6.8.0-110-generic

Install method

npm global

Model

anthropic/claude-opus-4-7

Provider / routing chain

openclaw -> anthropic

Additional provider/model setup details

Not provider-specific. Reproducible from a vanilla npm-global install of 2026.4.26 against a fresh mirror dir.

Logs, screenshots, and evidence

Original failure on 2026.4.25 (chokidar branch, since fixed):

[memory] qmd memory unavailable; falling back to builtin: Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/qmd-manager-FuXCtSYP.js
[gateway] qmd memory startup initialization failed for agent "main": Cannot find package 'chokidar' imported from ~/.openclaw/plugin-runtime-deps/openclaw-2026.4.25-.../dist/manager-...js

Manual workaround that resolved the live incident (replicate per missing package):

cd ~/.openclaw/plugin-runtime-deps/openclaw-<version>
xargs -a /tmp/all-specs.txt npm install --no-save
# where /tmp/all-specs.txt is the manifest specs PLUS the 9 missing packages
# at versions read from the npm-global package.json

Impact and severity

Affected: any user on 2026.4.26 (and likely earlier) whose plugin/code path exercises one of the 9 imports (e.g. cron scheduling → croner, push notifications → web-push, archive/backup → tar, dotenv-driven config → dotenv). Severity: variable — module-not-found at first reach; in our case it cascaded into a gateway restart loop because the failing module was on the qmd-memory startup path. Frequency: every fresh install / version upgrade until the manifest catches up. Consequence: feature failure or, for hot-path imports, gateway-level outage.

Additional information

Suggested fix: derive the manifest from a static analysis of dist bare-imports during the build pipeline, so the two cannot drift. Sketch:

grep -rh '^import .* from "[^./n]' dist/*.js \
  | grep -oE 'from "[^"]+"' \
  | sed -E 's|from "(@[^/]+/[^/]+).*"|\1|; s|from "([^/"]+).*"|\1|' \
  | sort -u

…then resolve each to a version from the openclaw package.json's dependencies and write them to .openclaw-runtime-deps.json at build time.

extent analysis

TL;DR

Update the .openclaw-runtime-deps.json manifest to include the 9 missing packages by deriving it from a static analysis of dist bare-imports during the build pipeline.

Guidance

  • Identify the missing packages by running the provided grep command to find bare imports in the dist code.
  • Verify that these packages are listed as direct dependencies in the openclaw npm package.json.
  • Update the .openclaw-runtime-deps.json manifest to include the missing packages, using the suggested grep and sed commands to derive the list from the dist code.
  • Test the updated manifest by reinstalling the dependencies and verifying that the missing packages are now included in the mirror.

Example

The suggested fix involves running the following command to derive the list of missing packages:

grep -rh '^import .* from "[^./n]' dist/*.js \
  | grep -oE 'from "[^"]+"' \
  | sed -E 's|from "(@[^/]+/[^/]+).*"|\1|; s|from "([^/"]+).*"|\1|' \
  | sort -u

This command can be used to generate the list of packages to include in the .openclaw-runtime-deps.json manifest.

Notes

The provided manual workaround can be used as a temporary solution to resolve the issue, but it is recommended to update the build pipeline to derive the manifest from the dist code to prevent similar issues in the future.

Recommendation

Apply the suggested fix to update the .openclaw-runtime-deps.json manifest by deriving it from a static analysis of dist bare-imports during the build pipeline, to ensure that the manifest includes all required packages and prevent similar issues in the future.

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

Every package the dist code imports as a bare specifier should be present in the mirror, either by being listed in .openclaw-runtime-deps.json (so the runtime installer adds it) or by being installed alongside the manifest specs.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: runtime-deps manifest still missing 9 dist bare-imports in 2026.4.26 (follow-up to #71420) [4 pull requests, 5 comments, 6 participants]