Docker runtime images fixed to use compiled plugins
A single environment variable override in Docker images was pointing plugin discovery to TypeScript source directories. On Node.js 24, this caused crash loops because the native TS loader doesn't remap .js imports to .ts files. Removing the override lets packaged installs use compiled JavaScript artifacts again, and containers boot properly.
Docker runtime images were shipping broken. A previous commit added an environment variable override that forced bundled plugin discovery to /app/extensions, the TypeScript source directory, instead of the compiled dist/extensions directory. On Node.js 24, which has native TypeScript support enabled, this caused an immediate crash loop: the runtime would load .ts files directly but then fail when encountering .js import statements that Node 24 couldn't resolve to their TypeScript counterparts.
The fix is surgical. Removing that single ENV OPENCLAW_BUNDLED_PLUGINS_DIR line lets the packaged-install resolver fall back to its default behavior, which already prefers compiled artifacts. The Matrix plugin—first visible reproducer in issue #62044—can now load alongside other bundled plugins without triggering the crash.
In the Docker runtime, packaged installs now use dist/extensions as intended. The Dockerfile guard test was also hardened to prevent this regression from slipping through again.
View Original GitHub Description
Summary
- Problem: the Docker runtime image forced bundled plugin discovery to
/app/extensions, which made packaged installs load raw source plugin entries instead of compiled runtime artifacts. - Why it matters: on Node 24 this can boot through source-only plugin paths and crash fresh containers, with Matrix surfacing first in issue #62044.
- What changed: removed the Docker
OPENCLAW_BUNDLED_PLUGINS_DIRoverride so packaged installs fall back to the normal resolver and usedist/extensions; updated the Dockerfile guard test; added a changelog fix entry. - What did NOT change (scope boundary): no plugin loader redesign, no source-runtime compatibility work, no broader plugin import refactor.
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 #62044
- Related #50058
- This PR fixes a bug or regression
Root Cause (if applicable)
- Root cause: commit
a2a9a553e1e03fcd6a3ec01196f3cd7b58710b7eadded a Docker runtime override that pinnedOPENCLAW_BUNDLED_PLUGINS_DIRto/app/extensions, bypassing the packaged-install resolver that already prefersdist/extensions. - Missing detection / guardrail: the Dockerfile test locked in the source-tree override instead of asserting packaged-runtime default behavior.
- Contributing context (if known): the issue became user-visible after the Node 24 runtime image path started executing against source plugin graphs that are not the intended packaged runtime surface.
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/dockerfile.test.ts - Scenario the test should lock in: runtime images must not override bundled plugin discovery away from packaged defaults.
- Why this is the smallest reliable guardrail: the regression was introduced directly in the Dockerfile and guarded by a Dockerfile-specific test.
- Existing test that already covers this (if any):
src/plugins/bundled-dir.test.tsalready covers packaged-install preference fordist/extensions. - If no new test is added, why not: existing Dockerfile guard test was updated instead of adding a duplicate.
User-visible / Behavior Changes
Docker runtime images now use compiled bundled plugin artifacts again instead of forcing source plugin discovery.
Diagram (if applicable)
Before:
[docker runtime] -> [/app/extensions override] -> [source plugin entrypoints] -> [Node 24 source-path crash]
After:
[docker runtime] -> [default packaged resolver] -> [dist/extensions] -> [compiled plugin artifacts]
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
- Runtime/container: local repo runtime; Docker packaging path
- Model/provider: N/A
- Integration/channel (if any): bundled Matrix plugin as first visible reproducer
- Relevant config (redacted): default packaged bundled-plugin resolution
Steps
- Inspect Docker runtime image config and bundled plugin resolver behavior.
- Verify source bundled plugin path is forced by the Dockerfile override.
- Remove the override so packaged installs fall back to
dist/extensions. - Run targeted tests and full build.
Expected
- Packaged Docker/runtime installs use compiled bundled plugin artifacts.
Actual
- Before fix, Docker runtime images forced source plugin discovery.
Evidence
Attach at least one:
- Failing test/log before + passing after
- Trace/log snippets
- Screenshot/recording
- Perf numbers (if relevant)
Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios:
pnpm test src/dockerfile.test.ts src/plugins/bundled-dir.test.ts;pnpm build - Edge cases checked: packaged resolver still prefers built bundled artifacts; Dockerfile no longer pins the wrong runtime env var.
- What you did not verify: full rebuilt Docker image boot smoke.
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.
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: a Docker-specific workflow may have been relying on source plugin discovery.
- Mitigation: packaged installs already prefer
dist/extensions, and the built plugin manifests are the intended runtime surface.
- Mitigation: packaged installs already prefer