Skip to content

[Feature]: Expose installBundledRuntimeDeps: false + make isolatedExecutionRoot default for bundled plugin runtime deps #75032

@Charpup

Description

@Charpup

Summary

Two adjacent config-surface changes to give operators an escape hatch from the bundled runtime deps lazy-stage cycle, which has been a recurring source of event-loop stalls and disk bloat (#74949, #73532, #56733, #74860 are all downstream symptoms).

What's already in source

Reading dist/bundled-runtime-deps-*.js and dist/loader-*.js in 2026.4.24 shows two relevant code paths that exist but are gated:

  1. loader-NucjcOgv.js:2240 references installBundledRuntimeDeps: false as an option — the code branch is there but isn't surfaced through openclaw.json config schema or CLI
  2. bundled-runtime-deps-BdEAdjwi.js#resolveBundledRuntimeDepsExternalBaseDir already implements an isolatedExecutionRoot path (separate staging dir + atomic replace) — but the default installExecutionRoot is the legacy shared-root path

Operators currently have to either patch package.json manually (per #74949) or apply OPENCLAW_PLUGIN_STAGE_DIR via systemd drop-in to get the isolated path. Neither is documented.

Proposed changes

1. Surface installBundledRuntimeDeps: false as a config field

# openclaw.json
{
  "plugins": {
    "installBundledRuntimeDeps": false   // default: true
  }
}

When false, the plugin loader should:

  • Skip the lazy-stage spawnSync entirely
  • Assume the operator has provided the runtime deps externally (e.g., via the host's package.json + npm install already done)
  • Fail fast with a clear error if a required plugin dep is missing, rather than silently re-installing

This is the proper fix for operators who:

2. Make isolatedExecutionRoot the default

The current default puts plugin deps installs at the same root the host openclaw uses. For multi-plugin deployments this causes the destructive prune problem #74949 describes (different plugins' lazy-stage cycles mutually pruning each other's deps).

Changing the default to the isolated path that already exists in source would:

  • Make a single-host, multi-plugin deployment safe out of the box
  • Remove the need for users to discover and apply the OPENCLAW_PLUGIN_STAGE_DIR env var as a workaround
  • Not change behavior for anyone explicitly opting into the legacy shared root

3. Document the resulting matrix

installBundledRuntimeDeps isolatedExecutionRoot Behavior
true (default) true (proposed default) Per-plugin isolated lazy-stage. No mutual prune. Cycles still happen but safe.
true false Legacy 2026.4.24 default. Destructive prune across plugins.
false n/a Operator-managed deps. No spawnSync. Plugin loader trusts host node_modules.

Why this matters

Giving operators these two knobs would let production deployments turn lazy-stage off entirely, while keeping the convenience for single-plugin / dev setups that benefit from the auto-install behavior.

Environment of the deployment that motivated this request

  • OpenClaw: 2026.4.24
  • Node: v22.22.0, npm: v10
  • Plugins enabled: discord, feishu, telegram, qqbot, wecom, ddingtalk, openai, kimi (8 channels)
  • Disk impact: ~38 GB cache bloat from repeated re-installs across ~14 days, 91% disk usage on a 120 GB volume before manual cleanup
  • Channel impact: Discord WebSocket invalid-session loops during npm storms; Feishu HTTP timeouts (axios 30s)

Happy to test patches against this deployment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions