openclaw - 💡(How to fix) Fix CLI crashes on jiti lazy getter access for bundled plugin contracts (4.7+) [1 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#63080Fetched 2026-04-09 07:58:49
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Author
Participants

Error Message

TypeError: Cannot read properties of undefined (reading 't') at Object.get [as legacyConfigRules] (.../extensions/slack/contract-api.js:1:647) at resolvePluginDoctorContracts (.../config-DMMR1XE_.js:220:52)

Root Cause

Two missing error boundaries in the plugin contract loading path:

Code Example

TypeError: Cannot read properties of undefined (reading 't')
    at Object.get [as legacyConfigRules] (.../extensions/slack/contract-api.js:1:647)
    at resolvePluginDoctorContracts (.../config-DMMR1XE_.js:220:52)

---

// Current (config-DMMR1XE_.js:214-221)
let mod;
try {
    mod = getJiti(contractSource)(contractSource);
} catch {
    continue;  // catches load errors
}
// These lines throw when jiti lazy getters fail:
const rules = coerceLegacyConfigRules(mod.default?.legacyConfigRules ?? mod.legacyConfigRules);
const normalizeCompatibilityConfig = ...

---

// Current (bundled-BUZYiQLp.js:256-262)
try {
    const plugin = entry.loadSetupPlugin();
    state.setupPluginsById.set(id, plugin);
    return plugin;
} finally {
    setupPluginLoadInProgressIds.delete(id);
}

---

let mod;
let rules;
let normalizeCompatibilityConfig;
try {
    mod = getJiti(contractSource)(contractSource);
    rules = coerceLegacyConfigRules(mod.default?.legacyConfigRules ?? mod.legacyConfigRules);
    normalizeCompatibilityConfig = coerceNormalizeCompatibilityConfig(
        mod.normalizeCompatibilityConfig ?? mod.default?.normalizeCompatibilityConfig
    );
} catch {
    continue;
}

---

try {
    const plugin = entry.loadSetupPlugin();
    state.setupPluginsById.set(id, plugin);
    return plugin;
} catch {
    return;
} finally {
    setupPluginLoadInProgressIds.delete(id);
}
RAW_BUFFERClick to expand / collapse

Bug

Since 2026.4.7, all CLI commands crash with:

TypeError: Cannot read properties of undefined (reading 't')
    at Object.get [as legacyConfigRules] (.../extensions/slack/contract-api.js:1:647)
    at resolvePluginDoctorContracts (.../config-DMMR1XE_.js:220:52)

This breaks openclaw cron list, openclaw cron add, openclaw message send, openclaw health, and all other CLI operations. The gateway process is unaffected (it uses native ESM imports).

Reproduced on 2026.4.7 and 2026.4.8. Not present in 2026.4.2.

Root cause

Two missing error boundaries in the plugin contract loading path:

1. resolvePluginDoctorContracts (config loader)

The Slack plugin's contract-api.js uses ESM imports. When loaded by jiti (CJS-compat), the imports become lazy getters on the module object. These getters throw when the underlying ESM resolution fails in the jiti context.

The current code wraps only the getJiti()() call in try/catch, but the property access on the returned module is outside the catch:

// Current (config-DMMR1XE_.js:214-221)
let mod;
try {
    mod = getJiti(contractSource)(contractSource);
} catch {
    continue;  // catches load errors
}
// These lines throw when jiti lazy getters fail:
const rules = coerceLegacyConfigRules(mod.default?.legacyConfigRules ?? mod.legacyConfigRules);
const normalizeCompatibilityConfig = ...

2. getBundledChannelSetupPlugin (bundled plugin loader)

The Telegram plugin's setup-entry.js references ./src/channel.setup.js which doesn't exist in the built package. The load call uses try/finally without a catch:

// Current (bundled-BUZYiQLp.js:256-262)
try {
    const plugin = entry.loadSetupPlugin();
    state.setupPluginsById.set(id, plugin);
    return plugin;
} finally {
    setupPluginLoadInProgressIds.delete(id);
}

Fix

Fix 1: Extend try/catch to cover lazy getter access

let mod;
let rules;
let normalizeCompatibilityConfig;
try {
    mod = getJiti(contractSource)(contractSource);
    rules = coerceLegacyConfigRules(mod.default?.legacyConfigRules ?? mod.legacyConfigRules);
    normalizeCompatibilityConfig = coerceNormalizeCompatibilityConfig(
        mod.normalizeCompatibilityConfig ?? mod.default?.normalizeCompatibilityConfig
    );
} catch {
    continue;
}

Fix 2: Add catch block for setup plugin loading

try {
    const plugin = entry.loadSetupPlugin();
    state.setupPluginsById.set(id, plugin);
    return plugin;
} catch {
    return;
} finally {
    setupPluginLoadInProgressIds.delete(id);
}

Environment

  • OpenClaw 2026.4.7 and 2026.4.8
  • Node.js 25.8.0
  • macOS (darwin)
  • Gateway runs as LaunchAgent on loopback

extent analysis

TL;DR

  • The most likely fix is to extend the try/catch blocks to cover lazy getter access and add a catch block for setup plugin loading to prevent crashes.

Guidance

  • Extend the try/catch block in resolvePluginDoctorContracts to cover the property access on the returned module, as shown in the provided Fix 1.
  • Add a catch block for setup plugin loading in getBundledChannelSetupPlugin to handle potential errors, as shown in the provided Fix 2.
  • Verify that the fixes resolve the crashes by running the affected CLI commands, such as openclaw cron list and openclaw message send.
  • Consider testing the fixes on different environments and Node.js versions to ensure compatibility.

Example

// Example of extended try/catch block
let mod;
let rules;
let normalizeCompatibilityConfig;
try {
    mod = getJiti(contractSource)(contractSource);
    rules = coerceLegacyConfigRules(mod.default?.legacyConfigRules ?? mod.legacyConfigRules);
    normalizeCompatibilityConfig = coerceNormalizeCompatibilityConfig(
        mod.normalizeCompatibilityConfig ?? mod.default?.normalizeCompatibilityConfig
    );
} catch {
    continue;
}

Notes

  • The provided fixes assume that the issue is caused by the missing error boundaries in the plugin contract loading path.
  • The fixes may need to be adapted or extended to cover other potential error scenarios.

Recommendation

  • Apply the provided workarounds (Fix 1 and Fix 2) to prevent crashes and ensure the CLI commands function correctly.

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…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING