openclaw - ✅(Solved) Fix [Bug]: pnpm prune --prod wipes dependencies of installed workspace packages in partial workspaces (pnpm 10) [5 pull requests, 1 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#49501Fetched 2026-04-08 00:54:35
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×5labeled ×2commented ×1

Inside a Docker build using pnpm 10, we use an 'opt-in' strategy where only a subset of workspace packages are initially installed via --filter. If we later add more packages and run pnpm prune --prod, pnpm v10 detects the 'incomplete' workspace and proceeds to wipe the established node_modules of the already installed packages.

Root Cause

Inside a Docker build using pnpm 10, we use an 'opt-in' strategy where only a subset of workspace packages are initially installed via --filter. If we later add more packages and run pnpm prune --prod, pnpm v10 detects the 'incomplete' workspace and proceeds to wipe the established node_modules of the already installed packages.

Fix Action

Fix / Workaround

  • pnpm Version: 10.23.0
    • Workaround: Using pnpm install --prod --offline --filter ... instead of pnpm prune --prod prevents the deletion. This is particularly critical for Docker builds that use a staged 'opt-in' installation strategy for workspace packages.

Affected: Docker builds / VPS deployments using staged installations. Severity: High (wiped dependencies block the runtime). Frequency: 100% repro in partial workspace builds. Consequence: Staged builds fail to run unless the workaround is used.

PR fix notes

PR #52675: fix(docker): avoid pnpm prune in partial workspaces

Description (problem / solution / changelog)

Summary

  • Problem: pnpm prune --prod on pnpm 10 wipes production dependencies for already-installed workspace extensions once the Docker build copies the full workspace into place.
  • Why it matters: Docker images built with OPENCLAW_EXTENSIONS can ship with missing runtime dependencies, breaking extension-backed deployments.
  • What changed: added a dedicated prod-deps stage that installs production dependencies before COPY . ., then copied runtime node_modules from that stage into the final image.
  • What did NOT change (scope boundary): build outputs, extension opt-in behavior, and runtime assets other than how production dependencies are assembled.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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 #49501
  • Related #49501

User-visible / Behavior Changes

Docker builds no longer rely on pnpm prune --prod after the full workspace copy, so opted-in extension dependencies stay present in the final runtime image under pnpm 10.

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: Windows 11 host
  • Runtime/container: Docker Desktop (desktop-linux), Node 24 bookworm Dockerfile, pnpm 10.23.0
  • Model/provider: N/A
  • Integration/channel (if any): Docker builds with OPENCLAW_EXTENSIONS
  • Relevant config (redacted): OPENCLAW_EXTENSIONS=matrix

Steps

  1. Install production deps for only a subset of workspace packages during the Docker build.
  2. Copy the full workspace into the image filesystem.
  3. Run pnpm prune --prod.

Expected

  • Existing production dependencies for the already-installed extension packages remain available in the runtime image.

Actual

  • pnpm 10 reconciles against the now-full workspace and wipes the previously installed extension dependencies.

Evidence

Attach at least one:

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

The new src/dockerfile.test.ts assertions fail against the pre-fix Dockerfile because it still uses pnpm prune --prod, lacks the prod-deps stage, and installs prod deps only after COPY . .. They pass with this patch.

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: ran pnpm exec vitest run --config vitest.unit.config.ts src/dockerfile.test.ts src/docker-build-cache.test.ts successfully.
  • Edge cases checked: confirmed the prod-deps stage copies opted-in extension manifests before install, runs before the full workspace copy, and is the source of runtime node_modules.
  • What you did not verify: attempted a Docker build for --target prod-deps, but Docker Hub auth timed out while fetching node:24-bookworm, so I did not complete an end-to-end image build in this environment.

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:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR's commit to restore the previous single-path dependency flow.
  • Files/config to restore: Dockerfile, src/dockerfile.test.ts
  • Known bad symptoms reviewers should watch for: missing extension runtime dependencies in Docker images, or regressions in the Dockerfile structure tests.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: a future runtime workspace package could need additional manifest copies in prod-deps.
    • Mitigation: the fix is scoped to the current runtime packaging model (root, UI, opted-in extensions), and the regression test now locks the required install ordering.

Changed files

  • .agent/workflows/update_clawdbot.md (modified, +7/-7)
  • .agents/skills/openclaw-ghsa-maintainer/SKILL.md (removed, +0/-87)
  • .agents/skills/openclaw-parallels-smoke/SKILL.md (removed, +0/-63)
  • .agents/skills/openclaw-pr-maintainer/SKILL.md (removed, +0/-75)
  • .agents/skills/openclaw-release-maintainer/SKILL.md (removed, +0/-74)
  • .agents/skills/openclaw-test-heap-leaks/SKILL.md (removed, +0/-71)
  • .agents/skills/openclaw-test-heap-leaks/agents/openai.yaml (removed, +0/-4)
  • .agents/skills/openclaw-test-heap-leaks/scripts/heapsnapshot-delta.mjs (removed, +0/-265)
  • .agents/skills/parallels-discord-roundtrip/SKILL.md (removed, +0/-62)
  • .agents/skills/security-triage/SKILL.md (removed, +0/-108)
  • .dockerignore (modified, +0/-6)
  • .github/CODEOWNERS (removed, +0/-54)
  • .github/ISSUE_TEMPLATE/bug_report.yml (modified, +25/-21)
  • .github/actions/ensure-base-commit/action.yml (modified, +2/-6)
  • .github/actions/setup-node-env/action.yml (modified, +2/-2)
  • .github/actions/setup-pnpm-store-cache/action.yml (modified, +2/-2)
  • .github/labeler.yml (modified, +14/-87)
  • .github/pull_request_template.md (modified, +1/-1)
  • .github/workflows/auto-response.yml (modified, +5/-10)
  • .github/workflows/ci.yml (modified, +345/-413)
  • .github/workflows/codeql.yml (modified, +5/-8)
  • .github/workflows/docker-release.yml (modified, +40/-123)
  • .github/workflows/install-smoke.yml (modified, +19/-104)
  • .github/workflows/labeler.yml (modified, +13/-16)
  • .github/workflows/openclaw-npm-release.yml (modified, +13/-129)
  • .github/workflows/plugin-npm-release.yml (removed, +0/-214)
  • .github/workflows/sandbox-common-smoke.yml (modified, +2/-7)
  • .github/workflows/stale.yml (modified, +9/-12)
  • .github/workflows/workflow-sanity.yml (modified, +2/-30)
  • .gitignore (modified, +5/-11)
  • .jscpd.json (removed, +0/-16)
  • .npmignore (modified, +0/-1)
  • .npmrc (modified, +0/-3)
  • .prettierignore (removed, +0/-1)
  • .secrets.baseline (modified, +4/-4)
  • AGENTS.md (modified, +143/-61)
  • CHANGELOG.md (modified, +122/-516)
  • CONTRIBUTING.md (modified, +4/-19)
  • Dockerfile (modified, +21/-5)
  • Dockerfile.sandbox (modified, +0/-1)
  • Dockerfile.sandbox-browser (modified, +0/-1)
  • Dockerfile.sandbox-common (modified, +0/-1)
  • README.md (modified, +14/-14)
  • Swabble/Sources/SwabbleKit/WakeWordGate.swift (modified, +13/-7)
  • Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift (modified, +0/-19)
  • appcast.xml (modified, +362/-76)
  • apps/android/README.md (modified, +3/-69)
  • apps/android/app/build.gradle.kts (modified, +7/-76)
  • apps/android/app/proguard-rules.pro (modified, +20/-0)
  • apps/android/app/src/main/AndroidManifest.xml (modified, +0/-2)
  • apps/android/app/src/main/java/ai/openclaw/app/MainActivity.kt (modified, +6/-16)
  • apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt (modified, +94/-163)
  • apps/android/app/src/main/java/ai/openclaw/app/NodeApp.kt (modified, +1/-12)
  • apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt (modified, +2/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt (modified, +54/-291)
  • apps/android/app/src/main/java/ai/openclaw/app/PermissionRequester.kt (modified, +21/-79)
  • apps/android/app/src/main/java/ai/openclaw/app/chat/ChatController.kt (modified, +10/-64)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CallLogHandler.kt (removed, +0/-247)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CameraCaptureManager.kt (modified, +30/-36)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt (modified, +3/-5)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CanvasController.kt (modified, +14/-52)
  • apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt (modified, +2/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/node/ContactsHandler.kt (modified, +2/-5)
  • apps/android/app/src/main/java/ai/openclaw/app/node/DeviceHandler.kt (modified, +2/-11)
  • apps/android/app/src/main/java/ai/openclaw/app/node/InvokeCommandRegistry.kt (modified, +5/-26)
  • apps/android/app/src/main/java/ai/openclaw/app/node/InvokeDispatcher.kt (modified, +3/-29)
  • apps/android/app/src/main/java/ai/openclaw/app/node/LocationCaptureManager.kt (modified, +9/-4)
  • apps/android/app/src/main/java/ai/openclaw/app/node/LocationHandler.kt (modified, +17/-75)
  • apps/android/app/src/main/java/ai/openclaw/app/node/MotionHandler.kt (modified, +18/-14)
  • apps/android/app/src/main/java/ai/openclaw/app/node/PhotosHandler.kt (modified, +34/-49)
  • apps/android/app/src/main/java/ai/openclaw/app/node/SmsHandler.kt (modified, +0/-12)
  • apps/android/app/src/main/java/ai/openclaw/app/node/SmsManager.kt (modified, +1/-384)
  • apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIAction.kt (modified, +3/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawProtocolConstants.kt (modified, +0/-11)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt (modified, +1/-12)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/ConnectTabScreen.kt (modified, +11/-64)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayConfigResolver.kt (modified, +2/-19)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayDiagnostics.kt (removed, +0/-77)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/MobileUiTokens.kt (modified, +24/-150)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt (modified, +229/-285)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/OpenClawTheme.kt (modified, +1/-18)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/PostOnboardingTabs.kt (modified, +45/-54)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/SettingsSheet.kt (modified, +8/-59)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/VoiceTabScreen.kt (modified, +2/-2)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/Base64ImageState.kt (modified, +4/-1)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt (modified, +6/-16)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatImageCodec.kt (removed, +0/-150)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMarkdown.kt (modified, +17/-21)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageListCard.kt (modified, +7/-16)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageViews.kt (modified, +3/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatSheetContent.kt (modified, +31/-11)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/ElevenLabsStreamingTts.kt (added, +338/-0)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/StreamingMediaDataSource.kt (added, +98/-0)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeGatewayConfig.kt (modified, +115/-4)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt (modified, +844/-126)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeVoiceResolver.kt (added, +122/-0)
  • apps/android/app/src/main/res/values-night/themes.xml (removed, +0/-8)
  • apps/android/app/src/play/AndroidManifest.xml (removed, +0/-13)
  • apps/android/app/src/test/java/ai/openclaw/app/chat/ChatControllerMessageIdentityTest.kt (removed, +0/-81)
  • apps/android/app/src/test/java/ai/openclaw/app/node/CallLogHandlerTest.kt (removed, +0/-193)

PR #52705: fix(docker): avoid pnpm prune in partial workspaces

Description (problem / solution / changelog)

Summary

  • Problem: pnpm prune --prod on pnpm 10 wipes production dependencies for already-installed workspace extensions once the Docker build copies the full workspace into place.
  • Why it matters: Docker images built with OPENCLAW_EXTENSIONS can ship with missing runtime dependencies, breaking extension-backed deployments.
  • What changed: added a dedicated prod-deps stage that installs production dependencies before COPY . ., then copied runtime node_modules from that stage into the final image.
  • What did NOT change (scope boundary): build outputs, extension opt-in behavior, and runtime assets other than how production dependencies are assembled.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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 #49501
  • Related #49501

User-visible / Behavior Changes

Docker builds no longer rely on pnpm prune --prod after the full workspace copy, so opted-in extension dependencies stay present in the final runtime image under pnpm 10.

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: Windows 11 host
  • Runtime/container: Docker Desktop (desktop-linux), Node 24 bookworm Dockerfile, pnpm 10.23.0
  • Model/provider: N/A
  • Integration/channel (if any): Docker builds with OPENCLAW_EXTENSIONS
  • Relevant config (redacted): OPENCLAW_EXTENSIONS=matrix

Steps

  1. Install production deps for only a subset of workspace packages during the Docker build.
  2. Copy the full workspace into the image filesystem.
  3. Run pnpm prune --prod.

Expected

  • Existing production dependencies for the already-installed extension packages remain available in the runtime image.

Actual

  • pnpm 10 reconciles against the now-full workspace and wipes the previously installed extension dependencies.

Evidence

Attach at least one:

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

The new src/dockerfile.test.ts assertions fail against the pre-fix Dockerfile because it still uses pnpm prune --prod, lacks the prod-deps stage, and installs prod deps only after COPY . .. They pass with this patch.

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: ran pnpm exec vitest run --config vitest.unit.config.ts src/dockerfile.test.ts src/docker-build-cache.test.ts successfully.
  • Edge cases checked: confirmed the prod-deps stage copies opted-in extension manifests before install, runs before the full workspace copy, and is the source of runtime node_modules.
  • What you did not verify: attempted a Docker build for --target prod-deps, but Docker Hub auth timed out while fetching node:24-bookworm, so I did not complete an end-to-end image build in this environment.

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:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR's commit to restore the previous single-path dependency flow.
  • Files/config to restore: Dockerfile, src/dockerfile.test.ts
  • Known bad symptoms reviewers should watch for: missing extension runtime dependencies in Docker images, or regressions in the Dockerfile structure tests.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: a future runtime workspace package could need additional manifest copies in prod-deps.
    • Mitigation: the fix is scoped to the current runtime packaging model (root, UI, opted-in extensions), and the regression test now locks the required install ordering.

Changed files

  • .agent/workflows/update_clawdbot.md (modified, +7/-7)
  • .agents/skills/openclaw-ghsa-maintainer/SKILL.md (removed, +0/-87)
  • .agents/skills/openclaw-parallels-smoke/SKILL.md (removed, +0/-63)
  • .agents/skills/openclaw-pr-maintainer/SKILL.md (removed, +0/-75)
  • .agents/skills/openclaw-release-maintainer/SKILL.md (removed, +0/-74)
  • .agents/skills/openclaw-test-heap-leaks/SKILL.md (removed, +0/-71)
  • .agents/skills/openclaw-test-heap-leaks/agents/openai.yaml (removed, +0/-4)
  • .agents/skills/openclaw-test-heap-leaks/scripts/heapsnapshot-delta.mjs (removed, +0/-265)
  • .agents/skills/parallels-discord-roundtrip/SKILL.md (removed, +0/-62)
  • .agents/skills/security-triage/SKILL.md (removed, +0/-108)
  • .dockerignore (modified, +0/-6)
  • .github/CODEOWNERS (removed, +0/-54)
  • .github/ISSUE_TEMPLATE/bug_report.yml (modified, +25/-21)
  • .github/actions/ensure-base-commit/action.yml (modified, +2/-6)
  • .github/actions/setup-node-env/action.yml (modified, +2/-2)
  • .github/actions/setup-pnpm-store-cache/action.yml (modified, +2/-2)
  • .github/labeler.yml (modified, +14/-87)
  • .github/pull_request_template.md (modified, +1/-1)
  • .github/workflows/auto-response.yml (modified, +5/-10)
  • .github/workflows/ci.yml (modified, +345/-413)
  • .github/workflows/codeql.yml (modified, +5/-8)
  • .github/workflows/docker-release.yml (modified, +40/-123)
  • .github/workflows/install-smoke.yml (modified, +19/-104)
  • .github/workflows/labeler.yml (modified, +13/-16)
  • .github/workflows/openclaw-npm-release.yml (modified, +13/-129)
  • .github/workflows/plugin-npm-release.yml (removed, +0/-214)
  • .github/workflows/sandbox-common-smoke.yml (modified, +2/-7)
  • .github/workflows/stale.yml (modified, +9/-12)
  • .github/workflows/workflow-sanity.yml (modified, +2/-30)
  • .gitignore (modified, +5/-11)
  • .jscpd.json (removed, +0/-16)
  • .npmignore (modified, +0/-1)
  • .npmrc (modified, +0/-3)
  • .prettierignore (removed, +0/-1)
  • .secrets.baseline (modified, +4/-4)
  • AGENTS.md (modified, +143/-61)
  • CHANGELOG.md (modified, +122/-522)
  • CONTRIBUTING.md (modified, +4/-19)
  • Dockerfile (modified, +21/-5)
  • Dockerfile.sandbox (modified, +0/-1)
  • Dockerfile.sandbox-browser (modified, +0/-1)
  • Dockerfile.sandbox-common (modified, +0/-1)
  • README.md (modified, +14/-14)
  • Swabble/Sources/SwabbleKit/WakeWordGate.swift (modified, +13/-7)
  • Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift (modified, +0/-19)
  • appcast.xml (modified, +362/-76)
  • apps/android/README.md (modified, +3/-69)
  • apps/android/app/build.gradle.kts (modified, +7/-76)
  • apps/android/app/proguard-rules.pro (modified, +20/-0)
  • apps/android/app/src/main/AndroidManifest.xml (modified, +0/-2)
  • apps/android/app/src/main/java/ai/openclaw/app/MainActivity.kt (modified, +6/-16)
  • apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt (modified, +94/-163)
  • apps/android/app/src/main/java/ai/openclaw/app/NodeApp.kt (modified, +1/-12)
  • apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt (modified, +2/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/NodeRuntime.kt (modified, +54/-291)
  • apps/android/app/src/main/java/ai/openclaw/app/PermissionRequester.kt (modified, +21/-79)
  • apps/android/app/src/main/java/ai/openclaw/app/chat/ChatController.kt (modified, +10/-64)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CallLogHandler.kt (removed, +0/-247)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CameraCaptureManager.kt (modified, +30/-36)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt (modified, +3/-5)
  • apps/android/app/src/main/java/ai/openclaw/app/node/CanvasController.kt (modified, +14/-52)
  • apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt (modified, +2/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/node/ContactsHandler.kt (modified, +2/-5)
  • apps/android/app/src/main/java/ai/openclaw/app/node/DeviceHandler.kt (modified, +2/-11)
  • apps/android/app/src/main/java/ai/openclaw/app/node/InvokeCommandRegistry.kt (modified, +5/-26)
  • apps/android/app/src/main/java/ai/openclaw/app/node/InvokeDispatcher.kt (modified, +3/-29)
  • apps/android/app/src/main/java/ai/openclaw/app/node/LocationCaptureManager.kt (modified, +9/-4)
  • apps/android/app/src/main/java/ai/openclaw/app/node/LocationHandler.kt (modified, +17/-75)
  • apps/android/app/src/main/java/ai/openclaw/app/node/MotionHandler.kt (modified, +18/-14)
  • apps/android/app/src/main/java/ai/openclaw/app/node/PhotosHandler.kt (modified, +34/-49)
  • apps/android/app/src/main/java/ai/openclaw/app/node/SmsHandler.kt (modified, +0/-12)
  • apps/android/app/src/main/java/ai/openclaw/app/node/SmsManager.kt (modified, +1/-384)
  • apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawCanvasA2UIAction.kt (modified, +3/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/protocol/OpenClawProtocolConstants.kt (modified, +0/-11)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt (modified, +1/-12)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/ConnectTabScreen.kt (modified, +11/-64)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayConfigResolver.kt (modified, +2/-19)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/GatewayDiagnostics.kt (removed, +0/-77)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/MobileUiTokens.kt (modified, +24/-150)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt (modified, +229/-285)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/OpenClawTheme.kt (modified, +1/-18)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/PostOnboardingTabs.kt (modified, +45/-54)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/SettingsSheet.kt (modified, +8/-59)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/VoiceTabScreen.kt (modified, +2/-2)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/Base64ImageState.kt (modified, +4/-1)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt (modified, +6/-16)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatImageCodec.kt (removed, +0/-150)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMarkdown.kt (modified, +17/-21)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageListCard.kt (modified, +7/-16)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageViews.kt (modified, +3/-6)
  • apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatSheetContent.kt (modified, +31/-11)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/ElevenLabsStreamingTts.kt (added, +338/-0)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/StreamingMediaDataSource.kt (added, +98/-0)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeGatewayConfig.kt (modified, +115/-4)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeManager.kt (modified, +844/-126)
  • apps/android/app/src/main/java/ai/openclaw/app/voice/TalkModeVoiceResolver.kt (added, +122/-0)
  • apps/android/app/src/main/res/values-night/themes.xml (removed, +0/-8)
  • apps/android/app/src/play/AndroidManifest.xml (removed, +0/-13)
  • apps/android/app/src/test/java/ai/openclaw/app/chat/ChatControllerMessageIdentityTest.kt (removed, +0/-81)
  • apps/android/app/src/test/java/ai/openclaw/app/node/CallLogHandlerTest.kt (removed, +0/-193)

PR #52710: fix(docker): avoid pnpm prune in partial workspaces

Description (problem / solution / changelog)

Summary

  • Problem: pnpm prune --prod on pnpm 10 wipes production dependencies for already-installed workspace extensions once the Docker build copies the full workspace into place.
  • Why it matters: Docker images built with OPENCLAW_EXTENSIONS can ship with missing runtime dependencies, breaking extension-backed deployments.
  • What changed: added a dedicated prod-deps stage that installs production dependencies before COPY . ., then copied runtime node_modules from that stage into the final image.
  • What did NOT change (scope boundary): build outputs, extension opt-in behavior, and runtime assets other than how production dependencies are assembled.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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 #49501
  • Related #49501

User-visible / Behavior Changes

Docker builds no longer rely on pnpm prune --prod after the full workspace copy, so opted-in extension dependencies stay present in the final runtime image under pnpm 10.

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: Windows 11 host
  • Runtime/container: Docker Desktop (desktop-linux), Node 24 bookworm Dockerfile, pnpm 10.23.0
  • Model/provider: N/A
  • Integration/channel (if any): Docker builds with OPENCLAW_EXTENSIONS
  • Relevant config (redacted): OPENCLAW_EXTENSIONS=matrix

Steps

  1. Install production deps for only a subset of workspace packages during the Docker build.
  2. Copy the full workspace into the image filesystem.
  3. Run pnpm prune --prod.

Expected

  • Existing production dependencies for the already-installed extension packages remain available in the runtime image.

Actual

  • pnpm 10 reconciles against the now-full workspace and wipes the previously installed extension dependencies.

Evidence

Attach at least one:

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

The new src/dockerfile.test.ts assertions fail against the pre-fix Dockerfile because it still uses pnpm prune --prod, lacks the prod-deps stage, and installs prod deps only after COPY . .. They pass with this patch.

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: ran pnpm exec vitest run --config vitest.unit.config.ts src/dockerfile.test.ts src/docker-build-cache.test.ts successfully.
  • Edge cases checked: confirmed the prod-deps stage copies opted-in extension manifests before install, runs before the full workspace copy, and is the source of runtime node_modules.
  • What you did not verify: attempted a Docker build for --target prod-deps, but Docker Hub auth timed out while fetching node:24-bookworm, so I did not complete an end-to-end image build in this environment.

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:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR's commit to restore the previous single-path dependency flow.
  • Files/config to restore: Dockerfile, src/dockerfile.test.ts
  • Known bad symptoms reviewers should watch for: missing extension runtime dependencies in Docker images, or regressions in the Dockerfile structure tests.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: a future runtime workspace package could need additional manifest copies in prod-deps.
    • Mitigation: the fix is scoped to the current runtime packaging model (root, UI, opted-in extensions), and the regression test now locks the required install ordering.

Changed files

  • Dockerfile (modified, +21/-5)
  • src/dockerfile.test.ts (modified, +14/-4)

PR #52726: read: recover from out-of-range offsets

Description (problem / solution / changelog)

Summary

  • Problem: read aborts the whole run when the requested offset is past EOF.
  • Why it matters: models regularly guess stale offsets after file changes, so this turns a recoverable paging mistake into a fatal tool failure.
  • What changed: the OpenClaw read wrapper now catches the upstream out-of-range offset error, recovers to a valid offset, and returns a diagnostic note plus content instead of throwing.
  • What did NOT change (scope boundary): this does not patch @mariozechner/pi-coding-agent itself or change normal in-range read behavior.

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 #52680
  • Related #49501

User-visible / Behavior Changes

  • read no longer aborts a run when offset is beyond EOF.
  • Out-of-range reads now return a diagnostic note and recover to a valid offset.
  • Limited reads recover to the last valid window instead of throwing.

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: Windows 11
  • Runtime/container: Node via pnpm test
  • Model/provider: N/A
  • Integration/channel (if any): agent read tool wrapper
  • Relevant config (redacted): default local test config

Steps

  1. Create a file with a few lines.
  2. Call read with offset larger than the file length.
  3. Observe the current tool error aborting the run.

Expected

  • The run should continue.
  • The tool should return a diagnostic and a valid recovery result.

Actual

  • Before this patch, the upstream read tool throws Offset ... is beyond end of file (...).

Evidence

  • 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: targeted Vitest coverage for out-of-range recovery and workspace-root guard behavior; manual tsx repro showing non-fatal recovery text for offset=200 on a 4-line file.
  • Edge cases checked: explicit limit now recovers to the last valid tail window instead of falling back to line 1.
  • What you did not verify: full repo pnpm test; a broad existing test file currently fails locally due a missing @modelcontextprotocol/sdk import chain unrelated to this change.

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:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert commit Read: recover from out-of-range offsets.
  • Files/config to restore: src/agents/pi-tools.read.ts
  • Known bad symptoms reviewers should watch for: unexpected read diagnostic notes on in-range offsets.

Risks and Mitigations

  • Risk: recovery window could return an unexpected chunk if upstream read paging defaults change again.
  • Mitigation: the wrapper only uses recovery for the specific upstream EOF-offset error and adds focused regression coverage for both unlimited and limited reads.

Changed files

  • src/agents/pi-tools.read.offset-recovery.test.ts (added, +115/-0)
  • src/agents/pi-tools.read.ts (modified, +140/-3)

PR #54122: fix(docker): avoid pnpm prune in partial workspaces

Description (problem / solution / changelog)

Supersedes #52710.

Summary

  • Problem: pnpm prune --prod ran after COPY . . expanded the full monorepo workspace, so partial-workspace Docker builds could drop runtime dependencies that were still needed by bundled extensions.
  • Why it matters: runtime images built with a narrowed extension set can lose extension-local production dependencies and fail at runtime.
  • What changed: replace the prune-based flow with a dedicated prod-deps stage that installs production dependencies before the full workspace copy, then copy both root node_modules and extension overlays from that prod graph into the runtime image.
  • Scope boundary: no runtime JS behavior changes outside the Docker image assembly path.

Change Type

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

Scope

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

Linked Issue/PR

  • Closes #49501
  • This PR fixes a bug or regression

Root Cause

  • The old Docker flow depended on pnpm prune --prod in runtime-assets after the full workspace had already been copied into the image.
  • Once pnpm saw the expanded monorepo, partial-workspace builds could prune away extension runtime dependencies that were still needed in the final image.
  • The fix is to install production dependencies from a minimal manifest-only workspace first, then reuse that resolved prod graph in the runtime stage.

Regression Test Plan

  • Unit test
  • Target file: src/dockerfile.test.ts
  • Scenarios locked in:
    • production dependencies install in a dedicated prod-deps stage
    • the prod install happens before COPY . .
    • runtime node_modules come from prod-deps, not from runtime-assets
    • extension overlays are copied from the same prod dependency graph
    • the Dockerfile no longer uses pnpm prune --prod

User-visible Changes

  • Docker images built from partial workspaces keep the production dependency graph needed by bundled extensions.

Security Impact

  • 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

Verification

  • pnpm test -- src/dockerfile.test.ts

Human Verification

  • Re-landed this as a clean latest-main PR with only Dockerfile and src/dockerfile.test.ts changes.
  • Verified the Dockerfile assertions cover the prod-deps stage ordering and runtime copy invariants.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: runtime and extension files could come from mismatched dependency graphs.
  • Mitigation: both root node_modules and bundled extension overlays are now copied from the same prod-deps stage.

Changed files

  • Dockerfile (modified, +29/-9)
  • src/dockerfile.test.ts (modified, +33/-3)
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Summary

Inside a Docker build using pnpm 10, we use an 'opt-in' strategy where only a subset of workspace packages are initially installed via --filter. If we later add more packages and run pnpm prune --prod, pnpm v10 detects the 'incomplete' workspace and proceeds to wipe the established node_modules of the already installed packages.

Steps to reproduce

  1. Create a pnpm workspace with multiple packages.
    1. Install dependencies for only a subset of packages (e.g., using --filter).
    1. Add the rest of the workspace package directories/manifests to the filesystem (so they appear in pnpm-workspace.yaml).
    1. Run pnpm prune --prod.
    1. Check the node_modules of the packages installed in step 2; they will be empty.

Expected behavior

pnpm prune should only remove devDependencies from existing installations and leave dependencies intact for the packages that were explicitly installed, even if the rest of the workspace is 'missing' modules.

Actual behavior

The established node_modules are wiped. This behavior seems like a regression or unexpected side effect of how pnpm 10 manages workspace state consistency during pruning.

OpenClaw version

main (2026.3.18)

Operating system

Docker (Node 24 Bookworm)

Install method

Docker

Model

N/A (build-time issue)

Provider / routing chain

N/A (build-time issue)

Config file / key location

No response

Additional provider/model setup details

  • pnpm Version: 10.23.0
    • Workaround: Using pnpm install --prod --offline --filter ... instead of pnpm prune --prod prevents the deletion. This is particularly critical for Docker builds that use a staged 'opt-in' installation strategy for workspace packages.

Logs, screenshots, and evidence

Impact and severity

Affected: Docker builds / VPS deployments using staged installations. Severity: High (wiped dependencies block the runtime). Frequency: 100% repro in partial workspace builds. Consequence: Staged builds fail to run unless the workaround is used.

Additional information

This behavior was observed after upgrading to pnpm 10. Existing Docker builds that used 'pnpm prune --prod' to clean up devDeps after mounting the full source now result in empty node_modules for previously installed packages.

extent analysis

Fix Plan

To fix the issue with pnpm prune --prod wiping the established node_modules of already installed packages in a partial workspace, you can use the following steps:

  • Instead of running pnpm prune --prod, use pnpm install --prod --offline --filter ... to prevent the deletion of dependencies.
  • Alternatively, you can also try using pnpm prune --prod --no-workspace-root-check to disable the workspace root check.

Example:

# Install dependencies for a subset of packages
pnpm install --filter package1,package2

# Add the rest of the workspace package directories/manifests to the filesystem

# Run pnpm install with --prod and --offline flags
pnpm install --prod --offline --filter package1,package2

Note: Replace package1,package2 with the actual package names you want to install.

Verification

To verify that the fix worked, check the node_modules directory of the packages installed in the first step. It should not be empty after running the pnpm install command with the --prod and --offline flags.

Extra Tips

  • Make sure to update your Docker build scripts to use the new command.
  • If you are using a pnpm-workspace.yaml file, ensure that it is correctly configured to include all the packages in the workspace.
  • You can also consider pinning the pnpm version to a specific version that works for your use case to avoid future regressions.

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

pnpm prune should only remove devDependencies from existing installations and leave dependencies intact for the packages that were explicitly installed, even if the rest of the workspace is 'missing' modules.

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]: pnpm prune --prod wipes dependencies of installed workspace packages in partial workspaces (pnpm 10) [5 pull requests, 1 comments, 2 participants]