Skip to content

[Bug]: @openclaw/codex fails before reply when local npm tree loses openclaw peer link #78185

@solavrc

Description

@solavrc

Summary

On OpenClaw 2026.5.4, Discord can receive a mention, create the reply thread, and show typing, but never send a response. The gateway error is a Codex harness import failure before any assistant reply:

Embedded agent failed before reply: Cannot find package 'openclaw' imported from /Users/local/.openclaw/npm/node_modules/@openclaw/codex/dist/shared-client-B7LbV3PF.js

Restoring the host OpenClaw peer link in the local external-plugin npm tree fixes the issue immediately:

ln -s /Users/local/.npm-global/lib/node_modules/openclaw /Users/local/.openclaw/npm/node_modules/openclaw
openclaw gateway restart

After that, importing the shared-client bundle succeeds and openclaw agent ... returns normally.

Why this seems upstream-relevant

This is similar to the previously fixed class of plugin peer-link issues, but it appears to still be reproducible through the @openclaw/codex packaged plugin path under ~/.openclaw/npm/node_modules.

Local package metadata shows @openclaw/codex declares openclaw as an optional peer dependency:

{
  "peerDependencies": {
    "openclaw": ">=2026.5.4-beta.1"
  },
  "peerDependenciesMeta": {
    "openclaw": {
      "optional": true
    }
  }
}

However, the generated runtime bundle imports openclaw at startup. That means update/install/repair flows can leave the package manager in a state that looks acceptable, while the Codex harness is guaranteed to fail before reply.

Observed environment

  • OpenClaw: 2026.5.4 (325df3e)
  • @openclaw/codex: 2026.5.4-beta.1
  • OS: macOS arm64
  • Node: 22.17.0
  • Install/update style: global openclaw with local OpenClaw workspace npm tree under ~/.openclaw/npm/node_modules
  • Discord channel status: connected and probe works
  • Failing path: /Users/local/.openclaw/npm/node_modules/@openclaw/codex/dist/shared-client-B7LbV3PF.js
  • Missing path before repair: /Users/local/.openclaw/npm/node_modules/openclaw
  • Existing host package path: /Users/local/.npm-global/lib/node_modules/openclaw

Reproduction shape

I do not yet have the exact update operation that deleted the link, but the broken state is easy to identify:

ls -la ~/.openclaw/npm/node_modules/openclaw
# No such file or directory

node -e "const { readdirSync } = require('node:fs'); const { join } = require('node:path'); const dir=process.env.HOME + '/.openclaw/npm/node_modules/@openclaw/codex/dist'; const file=readdirSync(dir).find((name)=>/^shared-client-.*\\.js$/.test(name)); console.log({file}); import(join(dir,file)).catch(e=>{console.error(e); process.exit(1)})"
# Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'openclaw' imported from .../shared-client-*.js

Then trigger the agent from Discord. Gateway logs show the harness failure and the Discord user sees typing/thread creation but no response.

Expected behavior

One or more of these should happen:

  1. The install/update/repair flow should ensure openclaw is linked into ~/.openclaw/npm/node_modules when @openclaw/codex needs it.
  2. @openclaw/codex should not mark openclaw as optional if the runtime bundle imports it unconditionally.
  3. Gateway startup or plugin repair should detect the missing peer link and repair or report it clearly.
  4. If a Discord turn has already become user-visible, harness startup failure should produce a visible error reply instead of silent typing/no response.

Actual behavior

  • Discord appears healthy and connected.
  • The bot creates a reply thread and shows typing.
  • Codex harness fails before reply with ERR_MODULE_NOT_FOUND.
  • No error is sent to the Discord user.

Workaround

ln -s /Users/local/.npm-global/lib/node_modules/openclaw /Users/local/.openclaw/npm/node_modules/openclaw
node -e "const { readdirSync } = require('node:fs'); const { join } = require('node:path'); const dir='/Users/local/.openclaw/npm/node_modules/@openclaw/codex/dist'; const file=readdirSync(dir).find((name)=>/^shared-client-.*\\.js$/.test(name)); if(!file) throw new Error('shared-client bundle not found'); import(join(dir,file)).then(()=>console.log('codex shared-client import ok')).catch(e=>{console.error(e.message); process.exit(1)})"
openclaw gateway restart
openclaw channels status --probe

After this, a direct diagnostic turn returned OK with agentHarnessId: "codex".

Related

Possibly related to the same broader peer-link failure class:

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