OS: Ubuntu 24.04.4 LTS
OpenClaw: 2026.4.8 (9ece252)
Problem: ran 'openclaw update', tried to update from 2026.4.5 to 2026.4.8. after update, 'doctor' shown required '@buape/carbon' and 'larksuiteoapi/node-sdk', then install both stacks. after reboot and 'openclaw doctor', msg shown "TypeError: Class extends value undefined is not a constructor or null".
Somebody can help on this one?
#TypeError: Class extends value undefined is not a constructor or null
1 messages · Page 1 of 1 (latest)
Yep — this one is usually a partial/broken runtime-deps install after update.
Try this exact sequence first:
openclaw --version
node -v
openclaw doctor --fix --yes
openclaw gateway restart
openclaw doctor
Two important notes:
node -vshould be >= 22.14- You shouldn’t need to manually install
@buape/carbon/@larksuiteoapi/node-sdkglobally —doctor --fixinstalls the pinned runtime deps in the correct OpenClaw install location.
If it still throws Class extends value undefined..., please paste output of:
openclaw --version
which openclaw
openclaw status --all
openclaw doctor
Then we can pinpoint whether it’s a broken global install path vs Node/runtime mismatch.
Docs:
ops@ops-Precision-3630-Tower:~$ openclaw --version
OpenClaw 2026.4.8 (9ece252)
ops@ops-Precision-3630-Tower:~$ which openclaw
/home/ops/.nvm/versions/node/v24.14.0/bin/openclaw
Perfect, thanks — that confirms your CLI path is the nvm global install, and Node version is fine.
Next step is to check if the install itself is corrupted/mixed:
openclaw doctor --fix --yes
openclaw status --all
If you still get the same Class extends value undefined... error, do a clean reinstall of OpenClaw in that nvm prefix:
pnpm remove -g openclaw
pnpm add -g openclaw@2026.4.8
openclaw doctor --fix --yes
openclaw gateway restart
openclaw doctor
If it still fails after that, paste the full output of:
openclaw doctor
openclaw gateway status
(especially the first file path in the stack trace). That’ll show exactly which module is throwing.
ops@ops-Precision-3630-Tower:~$ openclaw status --all
OpenClaw status --all
Item │ Value
│ Version │ 2026.4.8
│ OS │ linux 6.17.0-20-generic (x64)
│ Node │ 24.14.0
│ Config │ ~/.openclaw/openclaw.json
│ Dashboard │ http://127.0.0.1:18789/
│ Tailscale │ off
│ Channel │ stable (default)
│ Update │ pnpm · up to date · npm latest 2026.4.8
│ Gateway │ local · ws://127.0.0.1:18789 (local loopback) · reachable 81ms · auth token · ops-Precision-3630-Tower (10.60.20.29) │
│ │ app 2026.4.8 linux 6.17.0-20-generic
│ Security │ Run: openclaw security audit --deep
│ Gateway self │ unknown
│ Gateway service │ systemd installed · enabled · running (pid 7740, state active)
│ Node service │ systemd not installed
│ Agents │ 14 total · 0 bootstrapping · 0 active · 24 sessions
│ Secrets │ none
Diagnosis (read-only)
Gateway connection details:
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/ops/.openclaw/openclaw.json
Bind: loopback
✓ Config: /home/ops/.openclaw/openclaw.json
✓ Secret diagnostics (0)
✓ Restart sentinel: none
! Port 18789
Port 18789 is already in use.
- pid 7740 ops: openclaw-gateway (127.0.0.1:18789)
- Gateway already running locally. Stop it (openclaw gateway stop) or use a different port.
! Tailscale: off · unknown
✓ Skills: 14 eligible · 0 missing · /home/ops/.openclaw/workspace
✓ Plugin compatibility (none)
✓ Channel issues (none)
Nice — status --all looks healthy, so this is likely isolated to a doctor/plugin load path, not a dead gateway.
Can you run this and paste the full output?
openclaw doctor --fix --yes
If it still throws the same TypeError, then run a clean reinstall (same version) and retry:
pnpm remove -g openclaw
pnpm add -g openclaw@2026.4.8
openclaw doctor --fix --yes
If it still fails after reinstall, paste:
openclaw doctor
openclaw config get plugins.load.paths
The first stack-trace file path will tell us exactly which plugin/module is causing Class extends ... undefined.
ops@ops-Precision-3630-Tower:~$ openclaw doctor
TypeError: Class extends value undefined is not a constructor or null
This output actually looks good — I don’t see the Class extends value undefined... error anymore.
The Port 18789 is already in use warning just means your gateway is already running (openclaw-gateway pid 7740). That part is normal during diagnostics.
If you want a clean doctor run without that warning:
openclaw gateway stop
openclaw doctor --fix --yes
openclaw gateway start
If the TypeError still appears in another run, paste the first stack-trace lines and I’ll pinpoint the exact module.
Glad this looks much healthier now 🎉
Got it — thanks for confirming.
Since doctor still immediately throws, let’s do a clean CLI reinstall in your current nvm prefix (this usually fixes broken runtime deps/layout after update):
openclaw gateway stop
pnpm remove -g openclaw
pnpm store prune
pnpm add -g openclaw@2026.4.8
hash -r
openclaw doctor --fix --yes
openclaw gateway start
If it still errors after this, run this to get a real stack trace (not the short one-line message):
OPENCLAW_ROOT="$(dirname "$(dirname "$(which openclaw)")")/lib/node_modules/openclaw"
node --input-type=module -e "import('file://' + process.env.OPENCLAW_ROOT + '/dist/flows/doctor-health.js').then(m=>m.doctorCommand()).catch(e=>{console.error(e?.stack||e);process.exit(1)})"
Paste that output and I can pinpoint the exact module causing Class extends value undefined....
ops@ops-Precision-3630-Tower:~$ OPENCLAW_ROOT="$(dirname "$(dirname "$(which openclaw)")")/lib/node_modules/openclaw"
node --input-type=module -e "import('file://' + process.env.OPENCLAW_ROOT + '/dist/flows/doctor-health.js').then(m=>m.doctorCommand()).catch(e=>{console.error(e?.stack||e);process.exit(1)})"
TypeError [ERR_INVALID_FILE_URL_HOST]: File URL host must be "localhost" or empty on linux
at getPathFromURLPosix (node:internal/url:1561:11)
at fileURLToPath (node:internal/url:1609:63)
at finalizeResolution (node:internal/modules/esm/resolve:244:12)
at moduleResolve (node:internal/modules/esm/resolve:865:10)
at defaultResolve (node:internal/modules/esm/resolve:991:11)
at #cachedDefaultResolve (node:internal/modules/esm/loader:719:20)
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:736:38)
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:765:52)
at #resolve (node:internal/modules/esm/loader:701:17)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:621:35)
ops@ops-Precision-3630-Tower:~$
Nice catch — that error is from my command (your shell var wasn’t exported to node), not your original issue.
Use this corrected one-liner (it passes the path safely and gives the real stack):
OPENCLAW_ROOT="$(dirname "$(dirname "$(which openclaw)")")/lib/node_modules/openclaw" \
node --input-type=module -e "import { pathToFileURL } from 'node:url'; const mod = pathToFileURL(process.env.OPENCLAW_ROOT + '/dist/flows/doctor-health.js').href; import(mod).then(m => m.doctorCommand(undefined, { nonInteractive: true })).catch(e => { console.error(e?.stack || e); process.exit(1); });"
Paste that output and we can finally see which module/class is actually breaking.
ops@ops-Precision-3630-Tower:~$ OPENCLAW_ROOT="$(dirname "$(dirname "$(which openclaw)")")/lib/node_modules/openclaw"
node --input-type=module -e "import { pathToFileURL } from 'node:url'; const mod = pathToFileURL(process.env.OPENCLAW_ROOT + '/dist/flows/doctor-health.js').href; import(mod).then(m => m.doctorCommand(undefined, { nonInteractive: true })).catch(e => { console.error(e?.stack || e); process.exit(1); });"
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/ops/.nvm/versions/node/v24.14.0/lib/node_modules/openclaw/dist/flows/doctor-health.js' imported from /home/ops/[eval1]
at finalizeResolution (node:internal/modules/esm/resolve:275:11)
at moduleResolve (node:internal/modules/esm/resolve:865:10)
at defaultResolve (node:internal/modules/esm/resolve:991:11)
at #cachedDefaultResolve (node:internal/modules/esm/loader:719:20)
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:736:38)
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:765:52)
at #resolve (node:internal/modules/esm/loader:701:17)
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:621:35)
at onImport.tracePromise.proto (node:internal/modules/esm/loader:650:32)
at TracingChannel.tracePromise (node:diagnostics_channel:350:14)