Skip to content

fix(plugin-sdk): add export verification to prevent runtime breakage#28575

Merged
steipete merged 2 commits intoopenclaw:mainfrom
Glucksberg:fix/issue-27569
Mar 2, 2026
Merged

fix(plugin-sdk): add export verification to prevent runtime breakage#28575
steipete merged 2 commits intoopenclaw:mainfrom
Glucksberg:fix/issue-27569

Conversation

@Glucksberg
Copy link
Contributor

Summary

Adds regression guards for #27569 where isDangerousNameMatchingEnabled was missing from the compiled dist/plugin-sdk/index.js, causing mattermost (and potentially googlechat, msteams, irc) channel plugins to crash at runtime with TypeError: isDangerousNameMatchingEnabled is not a function.

  • Test coverage (src/plugin-sdk/index.test.ts): adds two new test cases that verify critical function and constant exports are present and callable from the plugin-sdk barrel. Covers isDangerousNameMatchingEnabled and 30+ other functions/constants that channel extensions depend on.
  • Release guard (scripts/release-check.ts): adds a checkPluginSdkExports() step that parses the compiled dist/plugin-sdk/index.js export statement and verifies 21 critical exports are present. Runs as part of pnpm release:check before every release.
  • Standalone check script (scripts/check-plugin-sdk-exports.mjs): can be run independently after pnpm build to verify plugin-sdk exports.

Test plan

  • pnpm vitest run src/plugin-sdk/index.test.ts passes (3 tests)
  • pnpm vitest run src/plugins/loader.test.ts passes (23 tests)
  • node --import tsx scripts/release-check.ts passes
  • node scripts/check-plugin-sdk-exports.mjs passes
  • pnpm tsgo clean

Closes #27569

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 27, 2026

Greptile Summary

Added comprehensive guards to prevent missing plugin-sdk exports that would cause runtime failures in channel extensions.

  • Test coverage (src/plugin-sdk/index.test.ts): adds verification for 30+ critical functions and constants that extensions depend on
  • Standalone check script (scripts/check-plugin-sdk-exports.mjs): verifies 21 critical exports in compiled output, can be run independently after build
  • Release guard (scripts/release-check.ts): integrated into release process, but only checks 17 exports instead of 21 (missing 4 critical functions)

Critical issue found: The release guard is incomplete - it's missing 4 exports that are checked by both the standalone script and the test file: buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled, and warnMissingProviderGroupPolicyFallbackOnce. This defeats the purpose of the release guard.

Confidence Score: 3/5

  • This PR has a critical bug that needs to be fixed before merging
  • The implementation approach is solid (comprehensive tests + dual guards), but there's a critical inconsistency: scripts/release-check.ts only verifies 17 exports while the standalone script and PR description claim 21. This means 4 critical exports won't be caught by the release guard, allowing the exact issue [Bug]: Mattermost channel fails to connect after updating to v2026.2.25 #27569 was meant to prevent. The tests are thorough, but the release guard - the most important safeguard - is incomplete.
  • scripts/release-check.ts needs the 4 missing exports added to match scripts/check-plugin-sdk-exports.mjs

Last reviewed commit: daecae9

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: daecae987e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +99 to +103
"logTypingFailure",
"resolveControlCommandGate",
"resolveDmGroupAccessWithLists",
"resolveAllowlistProviderRuntimeGroupPolicy",
"resolveDefaultGroupPolicy",

Choose a reason for hiding this comment

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

P2 Badge Align release export guard with plugin runtime imports

requiredPluginSdkExports omits several plugin-sdk symbols that channel extensions import at runtime (buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled, warnMissingProviderGroupPolicyFallbackOnce), so pnpm release:check can pass even when a future build drops one of these exports and extensions still crash with TypeError (for example the import set in extensions/mattermost/src/mattermost/monitor.ts includes them). This is also inconsistent with the stricter list in scripts/check-plugin-sdk-exports.mjs, which means the automated release gate is weaker than the standalone verifier introduced in the same commit.

Useful? React with 👍 / 👎.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 2e53fb3 — aligned the requiredPluginSdkExports list with the full set from check-plugin-sdk-exports.mjs, adding the 4 missing exports.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +92 to +110
const requiredPluginSdkExports = [
"isDangerousNameMatchingEnabled",
"createAccountListHelpers",
"buildAgentMediaPayload",
"createReplyPrefixOptions",
"createTypingCallbacks",
"logInboundDrop",
"logTypingFailure",
"resolveControlCommandGate",
"resolveDmGroupAccessWithLists",
"resolveAllowlistProviderRuntimeGroupPolicy",
"resolveDefaultGroupPolicy",
"resolveChannelMediaMaxBytes",
"emptyPluginConfigSchema",
"normalizePluginHttpPath",
"registerPluginHttpRoute",
"DEFAULT_ACCOUNT_ID",
"DEFAULT_GROUP_HISTORY_LIMIT",
];
Copy link
Contributor

Choose a reason for hiding this comment

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

4 critical exports are missing from this list compared to scripts/check-plugin-sdk-exports.mjs (which checks 21 exports):

Suggested change
const requiredPluginSdkExports = [
"isDangerousNameMatchingEnabled",
"createAccountListHelpers",
"buildAgentMediaPayload",
"createReplyPrefixOptions",
"createTypingCallbacks",
"logInboundDrop",
"logTypingFailure",
"resolveControlCommandGate",
"resolveDmGroupAccessWithLists",
"resolveAllowlistProviderRuntimeGroupPolicy",
"resolveDefaultGroupPolicy",
"resolveChannelMediaMaxBytes",
"emptyPluginConfigSchema",
"normalizePluginHttpPath",
"registerPluginHttpRoute",
"DEFAULT_ACCOUNT_ID",
"DEFAULT_GROUP_HISTORY_LIMIT",
];
const requiredPluginSdkExports = [
"isDangerousNameMatchingEnabled",
"createAccountListHelpers",
"buildAgentMediaPayload",
"createReplyPrefixOptions",
"createTypingCallbacks",
"logInboundDrop",
"logTypingFailure",
"buildPendingHistoryContextFromMap",
"clearHistoryEntriesIfEnabled",
"recordPendingHistoryEntryIfEnabled",
"resolveControlCommandGate",
"resolveDmGroupAccessWithLists",
"resolveAllowlistProviderRuntimeGroupPolicy",
"resolveDefaultGroupPolicy",
"resolveChannelMediaMaxBytes",
"warnMissingProviderGroupPolicyFallbackOnce",
"emptyPluginConfigSchema",
"normalizePluginHttpPath",
"registerPluginHttpRoute",
"DEFAULT_ACCOUNT_ID",
"DEFAULT_GROUP_HISTORY_LIMIT",
];
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/release-check.ts
Line: 92-110

Comment:
4 critical exports are missing from this list compared to `scripts/check-plugin-sdk-exports.mjs` (which checks 21 exports):

```suggestion
const requiredPluginSdkExports = [
  "isDangerousNameMatchingEnabled",
  "createAccountListHelpers",
  "buildAgentMediaPayload",
  "createReplyPrefixOptions",
  "createTypingCallbacks",
  "logInboundDrop",
  "logTypingFailure",
  "buildPendingHistoryContextFromMap",
  "clearHistoryEntriesIfEnabled",
  "recordPendingHistoryEntryIfEnabled",
  "resolveControlCommandGate",
  "resolveDmGroupAccessWithLists",
  "resolveAllowlistProviderRuntimeGroupPolicy",
  "resolveDefaultGroupPolicy",
  "resolveChannelMediaMaxBytes",
  "warnMissingProviderGroupPolicyFallbackOnce",
  "emptyPluginConfigSchema",
  "normalizePluginHttpPath",
  "registerPluginHttpRoute",
  "DEFAULT_ACCOUNT_ID",
  "DEFAULT_GROUP_HISTORY_LIMIT",
];
```

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 2e53fb3 — added buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled, and warnMissingProviderGroupPolicyFallbackOnce to align with the 21-export list in check-plugin-sdk-exports.mjs.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9857489ad9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


// Critical functions that channel extension plugins import from openclaw/plugin-sdk.
// If any are missing from the compiled output, plugins crash at runtime (#27569).
const requiredPluginSdkExports = [

Choose a reason for hiding this comment

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

P2 Badge Include all runtime plugin-sdk imports in release guard

checkPluginSdkExports() only verifies the 21 names in requiredPluginSdkExports, but runtime imports used by shipped extensions are missing from that list (for example createDedupeCache/formatInboundFromLabel in extensions/mattermost/src/mattermost/monitor-helpers.ts:1-7 and buildChannelKeyCandidates in extensions/msteams/src/policy.ts:12-16). If bundling drops one of those exports (the same failure mode as #27569), pnpm release:check will still pass and the affected extension will crash at runtime with TypeError.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector
Copy link

You have reached your Codex rate limits. Please try again later.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28221a4471

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +168 to +170
// Critical functions that channel extension plugins import from openclaw/plugin-sdk.
// If any are missing from the compiled output, plugins crash at runtime (#27569).
const requiredPluginSdkExports = [

Choose a reason for hiding this comment

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

P1 Badge Close appcast blocks before adding plugin-sdk export checks

The plugin-sdk export guard was inserted before checkAppcastSparkleVersions() closes its for/if blocks, leaving scripts/release-check.ts syntactically invalid; running node scripts/release-check.ts now fails with ERR_INVALID_TYPESCRIPT_SYNTAX: Expected '}', got '<eof>'. In this state pnpm release:check cannot run at all, so the release validation gate is effectively broken whenever release checks are invoked.

Useful? React with 👍 / 👎.

@steipete steipete merged commit 58e9ca2 into openclaw:main Mar 2, 2026
19 of 21 checks passed
@steipete
Copy link
Contributor

steipete commented Mar 2, 2026

Landed via temp rebase onto main.

  • Gate: pnpm check (fails on pre-existing main TS errors), pnpm build (same pre-existing TS error), pnpm vitest src/plugin-sdk/index.test.ts (pass), node scripts/check-plugin-sdk-exports.mjs (pass)
  • Land commit: 6e5160f
  • Merge commit: $merge_sha

Thanks @Glucksberg!

@steipete
Copy link
Contributor

steipete commented Mar 2, 2026

Correction (expanded SHAs):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scripts Repository scripts size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Mattermost channel fails to connect after updating to v2026.2.25

2 participants