Skip to content

fix(matrix): resolve crypto bootstrap failure and multi-extension idHint warning#53298

Merged
gumadeiras merged 5 commits intoopenclaw:mainfrom
keithce:fix/line-matrix-plugin-load-failures
Mar 29, 2026
Merged

fix(matrix): resolve crypto bootstrap failure and multi-extension idHint warning#53298
gumadeiras merged 5 commits intoopenclaw:mainfrom
keithce:fix/line-matrix-plugin-load-failures

Conversation

@keithce
Copy link
Copy Markdown
Contributor

@keithce keithce commented Mar 24, 2026

Summary

Fixes two issues with the Matrix plugin on current main:

  • Crypto bootstrap failure: Cannot read properties of undefined (reading 'ensureMatrixCryptoRuntime') — reported on every CLI invocation
  • Spurious idHint warning: plugin id mismatch (manifest uses "matrix", entry hints "matrix/index") — emitted after the build entry fix introduces a second extension entry

Note: The LINE TypeError: Cannot redefine property: isSenderAllowed was already fixed by #53221 (merged). This PR no longer touches the LINE extension.

Reproduction

$ openclaw models list

[plugins] matrix: failed loading crypto bootstrap runtime: Cannot read properties of undefined (reading 'ensureMatrixCryptoRuntime')

After the matrix package.json fix alone, a new warning appears on every invocation:

Config warnings:
- plugins.entries.matrix: plugin matrix: plugin id mismatch (manifest uses "matrix", entry hints "matrix/index")

Root Cause & Fix

Matrix: plugin-entry.runtime.ts not loadable in source-checkout mode

extensions/matrix/index.ts dynamically imports ./src/plugin-entry.runtime.js at registration time for crypto bootstrap. Two issues:

  1. Build: src/plugin-entry.runtime.ts was not listed in openclaw.extensions in package.json, so tsdown never compiled it to dist/extensions/matrix/src/plugin-entry.runtime.js.
  2. Source checkout: The gateway resolves bundled plugins from the source extensions/ tree (via isSourceCheckoutRoot in src/plugins/bundled-dir.ts). Native import() inside a jiti-loaded module uses Node's ESM loader, which cannot resolve .js.ts. The .js file doesn't exist in the source tree — only .ts does.

Fix:

  • Add ./src/plugin-entry.runtime.ts to the openclaw.extensions array in extensions/matrix/package.json so it's compiled to dist for production builds
  • Add a thin ESM .js wrapper at extensions/matrix/src/plugin-entry.runtime.js that uses jiti to load the .ts source, bridging the gap for source-checkout mode

Multi-extension idHint format not recognised

Adding a second entry to openclaw.extensions causes deriveIdHint in the metadata generator to return "matrix/index" instead of "matrix". isCompatiblePluginIdHint in src/plugins/manifest-registry.ts only accepts exact matches and four well-known suffixes — not the {id}/{entryBase} form.

Fix: Add a startsWith(\${manifestId}/`)check toisCompatiblePluginIdHint` so multi-extension idHints are accepted.

Files changed

  • extensions/matrix/package.json — add build entry
  • extensions/matrix/src/plugin-entry.runtime.js — new ESM wrapper for source-checkout mode
  • src/plugins/manifest-registry.ts — accept multi-extension idHint format
  • src/plugins/bundled-plugin-metadata.generated.ts — regenerated

Test plan

  • pnpm build succeeds
  • openclaw models list shows no matrix: failed loading crypto bootstrap runtime errors
  • openclaw models list shows no plugin id mismatch warnings
  • pnpm check passes (pre-existing msteams/ui tsgo errors excluded)
  • pnpm test -- src/plugins/manifest-registry.test.ts --run passes (26/26)
  • pnpm test -- extensions/matrix/src/matrix/client/file-sync-store.test.ts --run passes (7/7)

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 24, 2026 02:09
@openclaw-barnacle openclaw-barnacle bot added channel: line Channel integration: line channel: matrix Channel integration: matrix size: XS labels Mar 24, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR fixes two plugin-load failures on source-checkout startup: a TypeError: Cannot redefine property: isSenderAllowed in the LINE plugin caused by a self-importing barrel that double-exported the same symbol under jiti's CJS transform, and a Cannot read properties of undefined (reading 'ensureMatrixCryptoRuntime') in the Matrix plugin caused by a missing tsdown entry and an inability to resolve .ts files via Node's native ESM loader.

  • LINE (extensions/line/runtime-api.ts): Clean fix — replaces the circular openclaw/plugin-sdk/line-runtime self-import with direct export * for the four modules that were only accessible through it, eliminating the duplicate Object.defineProperty call.
  • Matrix (extensions/matrix/src/plugin-entry.runtime.js): Adds a thin ESM wrapper that uses jiti to load plugin-entry.runtime.ts in source-checkout mode; the four exported names match the TypeScript source exactly.
  • Matrix (extensions/matrix/package.json): Adds ./src/plugin-entry.runtime.ts to openclaw.extensions so tsdown compiles it for production. The side-effect is that the metadata generator now sets hasMultipleExtensions: true for the matrix entry and produces idHint: "matrix/index" (instead of "matrix").
  • Generated metadata (src/plugins/bundled-plugin-metadata.generated.ts): The idHint: "matrix/index" value does not match the manifest.id of "matrix", and isCompatiblePluginIdHint only recognises exact matches and four hard-coded suffixes. This triggers a warn-level diagnostic on every CLI invocation — not a load failure, but a spurious diagnostic entry. Either isCompatiblePluginIdHint should be extended to accept the {id}/{entryBase} pattern that the generator now produces for multi-extension plugins, or deriveIdHint should stop appending /{base} since no current consumer needs the disambiguation.

Confidence Score: 4/5

  • Safe to merge with one targeted follow-up: the idHint: "matrix/index" value introduced by the multi-extension change will emit a spurious warn-level diagnostic from isCompatiblePluginIdHint on every invocation.
  • Both root-cause fixes are correct and well-scoped. The LINE fix cleanly removes the self-import cycle; the Matrix wrapper correctly re-exports all four symbols and handles source-checkout resolution. The only unresolved issue is the idHint mismatch warning, which does not block plugin loading but should be addressed in a quick follow-up.
  • src/plugins/bundled-plugin-metadata.generated.ts (idHint: "matrix/index" not recognised by isCompatiblePluginIdHint) and src/plugins/manifest-registry.ts (isCompatiblePluginIdHint needs to handle the {id}/{base} format)
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/plugins/bundled-plugin-metadata.generated.ts
Line: 1549

Comment:
**`idHint` format not recognised by `isCompatiblePluginIdHint`**

Because `extensions/matrix/package.json` now has two entries in `extensions`, `scripts/generate-bundled-plugin-metadata.mjs`'s `deriveIdHint` sets `hasMultipleExtensions: true` and returns `"${normalizedPackageId}/${base}"``"matrix/index"`.

`isCompatiblePluginIdHint` in `src/plugins/manifest-registry.ts` only recognises the exact manifest ID or the four well-known suffixes (`-provider`, `-plugin`, `-sandbox`, `-media-understanding`); `"matrix/index"` matches none of those for the manifest ID `"matrix"`. That means every time the bundled plugin metadata is used (i.e. every `openclaw` invocation), a `warn`-level diagnostic is emitted:

> `plugin id mismatch (manifest uses "matrix", entry hints "matrix/index")`

The diagnostic doesn't stop the plugin from loading, but it does pollute the registry's diagnostic array and may surface in CLI output or `diagnostics` commands.

The cleanest fix is to extend `isCompatiblePluginIdHint` to also accept the `{id}/{anything}` form that the generator now produces:

```ts
// manifest-registry.ts
function isCompatiblePluginIdHint(idHint: string | undefined, manifestId: string): boolean {
  const normalizedHint = idHint?.trim();
  if (!normalizedHint) return true;
  if (normalizedHint === manifestId) return true;
  // Generated idHint for multi-extension plugins takes the form "id/entryBase"
  if (normalizedHint.startsWith(`${manifestId}/`)) return true;
  return (
    normalizedHint === `${manifestId}-provider` ||
    normalizedHint === `${manifestId}-plugin` ||
    normalizedHint === `${manifestId}-sandbox` ||
    normalizedHint === `${manifestId}-media-understanding`
  );
}
```

Alternatively, the generator's `deriveIdHint` could keep returning just `normalizedPackageId` regardless of `hasMultipleExtensions`, since the disambiguation is not actually needed by any consumer.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(line,matrix): resolve plugin load fa..." | Re-trigger Greptile

{
dirName: "matrix",
idHint: "matrix",
idHint: "matrix/index",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 idHint format not recognised by isCompatiblePluginIdHint

Because extensions/matrix/package.json now has two entries in extensions, scripts/generate-bundled-plugin-metadata.mjs's deriveIdHint sets hasMultipleExtensions: true and returns "${normalizedPackageId}/${base}""matrix/index".

isCompatiblePluginIdHint in src/plugins/manifest-registry.ts only recognises the exact manifest ID or the four well-known suffixes (-provider, -plugin, -sandbox, -media-understanding); "matrix/index" matches none of those for the manifest ID "matrix". That means every time the bundled plugin metadata is used (i.e. every openclaw invocation), a warn-level diagnostic is emitted:

plugin id mismatch (manifest uses "matrix", entry hints "matrix/index")

The diagnostic doesn't stop the plugin from loading, but it does pollute the registry's diagnostic array and may surface in CLI output or diagnostics commands.

The cleanest fix is to extend isCompatiblePluginIdHint to also accept the {id}/{anything} form that the generator now produces:

// manifest-registry.ts
function isCompatiblePluginIdHint(idHint: string | undefined, manifestId: string): boolean {
  const normalizedHint = idHint?.trim();
  if (!normalizedHint) return true;
  if (normalizedHint === manifestId) return true;
  // Generated idHint for multi-extension plugins takes the form "id/entryBase"
  if (normalizedHint.startsWith(`${manifestId}/`)) return true;
  return (
    normalizedHint === `${manifestId}-provider` ||
    normalizedHint === `${manifestId}-plugin` ||
    normalizedHint === `${manifestId}-sandbox` ||
    normalizedHint === `${manifestId}-media-understanding`
  );
}

Alternatively, the generator's deriveIdHint could keep returning just normalizedPackageId regardless of hasMultipleExtensions, since the disambiguation is not actually needed by any consumer.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugins/bundled-plugin-metadata.generated.ts
Line: 1549

Comment:
**`idHint` format not recognised by `isCompatiblePluginIdHint`**

Because `extensions/matrix/package.json` now has two entries in `extensions`, `scripts/generate-bundled-plugin-metadata.mjs`'s `deriveIdHint` sets `hasMultipleExtensions: true` and returns `"${normalizedPackageId}/${base}"``"matrix/index"`.

`isCompatiblePluginIdHint` in `src/plugins/manifest-registry.ts` only recognises the exact manifest ID or the four well-known suffixes (`-provider`, `-plugin`, `-sandbox`, `-media-understanding`); `"matrix/index"` matches none of those for the manifest ID `"matrix"`. That means every time the bundled plugin metadata is used (i.e. every `openclaw` invocation), a `warn`-level diagnostic is emitted:

> `plugin id mismatch (manifest uses "matrix", entry hints "matrix/index")`

The diagnostic doesn't stop the plugin from loading, but it does pollute the registry's diagnostic array and may surface in CLI output or `diagnostics` commands.

The cleanest fix is to extend `isCompatiblePluginIdHint` to also accept the `{id}/{anything}` form that the generator now produces:

```ts
// manifest-registry.ts
function isCompatiblePluginIdHint(idHint: string | undefined, manifestId: string): boolean {
  const normalizedHint = idHint?.trim();
  if (!normalizedHint) return true;
  if (normalizedHint === manifestId) return true;
  // Generated idHint for multi-extension plugins takes the form "id/entryBase"
  if (normalizedHint.startsWith(`${manifestId}/`)) return true;
  return (
    normalizedHint === `${manifestId}-provider` ||
    normalizedHint === `${manifestId}-plugin` ||
    normalizedHint === `${manifestId}-sandbox` ||
    normalizedHint === `${manifestId}-media-understanding`
  );
}
```

Alternatively, the generator's `deriveIdHint` could keep returning just `normalizedPackageId` regardless of `hasMultipleExtensions`, since the disambiguation is not actually needed by any consumer.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes recurring plugin load failures in source-checkout mode by removing a problematic LINE runtime self-import that caused duplicate star-export collisions, and by making Matrix’s crypto bootstrap runtime loadable via dynamic import during source-checkout startup.

Changes:

  • LINE: remove openclaw/plugin-sdk/line-runtime self-import from extensions/line/runtime-api.ts and export needed modules directly to avoid Cannot redefine property errors under jiti.
  • Matrix: ensure src/plugin-entry.runtime.ts is built (added to openclaw.extensions) and add an ESM .js wrapper to allow native import() to work in source checkouts.
  • Regenerate bundled plugin metadata to reflect Matrix’s additional extension entry.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
extensions/line/runtime-api.ts Removes the self-import path that caused duplicate export collisions; adds direct exports for modules previously reachable via the SDK barrel.
extensions/matrix/package.json Adds ./src/plugin-entry.runtime.ts to openclaw.extensions so it’s compiled to dist for production.
extensions/matrix/src/plugin-entry.runtime.js Adds an ESM wrapper that uses jiti to load the TS runtime in source-checkout mode.
src/plugins/bundled-plugin-metadata.generated.ts Updates generated bundled metadata for Matrix (additional extension entry; idHint change).

{
dirName: "matrix",
idHint: "matrix",
idHint: "matrix/index",
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idHint is now "matrix/index", but the bundled Matrix manifest id is "matrix". manifest-registry.ts treats this as an incompatible hint and will emit a startup warning (plugin id mismatch ... entry hints "matrix/index"). Consider keeping idHint compatible with the manifest id for the primary bundled entry (e.g., adjust the bundled metadata generator so multi-extension packages don't append "/index" to the first entry), to avoid introducing a new always-on warning during plugin discovery.

Suggested change
idHint: "matrix/index",
idHint: "matrix",

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +12
export const ensureMatrixCryptoRuntime = mod.ensureMatrixCryptoRuntime;
export const handleVerifyRecoveryKey = mod.handleVerifyRecoveryKey;
export const handleVerificationBootstrap = mod.handleVerificationBootstrap;
export const handleVerificationStatus = mod.handleVerificationStatus;
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wrapper is critical to source-checkout startup, but there’s no regression test covering that import("./src/plugin-entry.runtime.js") succeeds and provides the expected named exports. Adding a small Matrix extension test that imports this wrapper (via the same Jiti path the plugin loader uses) and asserts the exported functions exist would help prevent future startup regressions.

Suggested change
export const ensureMatrixCryptoRuntime = mod.ensureMatrixCryptoRuntime;
export const handleVerifyRecoveryKey = mod.handleVerifyRecoveryKey;
export const handleVerificationBootstrap = mod.handleVerificationBootstrap;
export const handleVerificationStatus = mod.handleVerificationStatus;
const {
ensureMatrixCryptoRuntime,
handleVerifyRecoveryKey,
handleVerificationBootstrap,
handleVerificationStatus,
} = mod;
for (const [name, fn] of Object.entries({
ensureMatrixCryptoRuntime,
handleVerifyRecoveryKey,
handleVerificationBootstrap,
handleVerificationStatus,
})) {
if (typeof fn !== "function") {
throw new Error(
`Expected '${name}' to be a function exported from ./plugin-entry.runtime.ts`
);
}
}
export {
ensureMatrixCryptoRuntime,
handleVerifyRecoveryKey,
handleVerificationBootstrap,
handleVerificationStatus,
};

Copilot uses AI. Check for mistakes.
@keithce keithce force-pushed the fix/line-matrix-plugin-load-failures branch from e05d3cc to 2880add Compare March 24, 2026 14:50
@keithce keithce changed the title fix(line,matrix): resolve plugin load failures on source-checkout startup fix(matrix): resolve crypto bootstrap failure and multi-extension idHint warning Mar 24, 2026
@openclaw-barnacle openclaw-barnacle bot removed the channel: line Channel integration: line label Mar 24, 2026
@gumadeiras gumadeiras self-assigned this Mar 29, 2026
@gumadeiras gumadeiras force-pushed the fix/line-matrix-plugin-load-failures branch from 016914e to 2b050e2 Compare March 29, 2026 06:57
@gumadeiras gumadeiras requested a review from a team as a code owner March 29, 2026 06:57
@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: S and removed size: XS labels Mar 29, 2026
@gumadeiras gumadeiras force-pushed the fix/line-matrix-plugin-load-failures branch from 2b050e2 to 85e29ad Compare March 29, 2026 07:03
Molt Bot and others added 5 commits March 29, 2026 12:00
…int warning

Add ./src/plugin-entry.runtime.ts to the matrix openclaw.extensions build
entry list so tsdown compiles it to dist, and add a thin ESM .js wrapper
in the source tree so that native dynamic import() resolves correctly in
source-checkout mode (jiti only intercepts require, not import).

Extend isCompatiblePluginIdHint to accept the id/entryBase format that
deriveIdHint produces for multi-extension plugins, preventing a spurious
warn diagnostic on every CLI invocation.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@gumadeiras gumadeiras force-pushed the fix/line-matrix-plugin-load-failures branch from 85e29ad to 6f5813f Compare March 29, 2026 16:37
@openclaw-barnacle openclaw-barnacle bot removed the agents Agent runtime and tooling label Mar 29, 2026
@gumadeiras gumadeiras merged commit 2d2e386 into openclaw:main Mar 29, 2026
17 of 20 checks passed
@gumadeiras
Copy link
Copy Markdown
Member

Merged via squash.

Thanks @keithce!

alexjiang1 pushed a commit to alexjiang1/openclaw that referenced this pull request Mar 31, 2026
…int warning (openclaw#53298)

Merged via squash.

Prepared head SHA: 6f5813f
Co-authored-by: keithce <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras
livingghost pushed a commit to livingghost/openclaw that referenced this pull request Mar 31, 2026
…int warning (openclaw#53298)

Merged via squash.

Prepared head SHA: 6f5813f
Co-authored-by: keithce <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras
pgondhi987 pushed a commit to pgondhi987/openclaw that referenced this pull request Mar 31, 2026
…int warning (openclaw#53298)

Merged via squash.

Prepared head SHA: 6f5813f
Co-authored-by: keithce <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: matrix Channel integration: matrix size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants