Skip to content

fix(feishu): guard channelRuntime inbound before dispatch fallback (fixes #93453)#93472

Closed
xzh-icenter wants to merge 3 commits into
openclaw:mainfrom
xzh-icenter:fix/feishu-dispatch-missing-inbound
Closed

fix(feishu): guard channelRuntime inbound before dispatch fallback (fixes #93453)#93472
xzh-icenter wants to merge 3 commits into
openclaw:mainfrom
xzh-icenter:fix/feishu-dispatch-missing-inbound

Conversation

@xzh-icenter

@xzh-icenter xzh-icenter commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #93453

After upgrading to 2026.6.6, the Feishu channel dispatch crashes with TypeError: Cannot read properties of undefined (reading run) when the gateway provides a partial channelRuntime object that lacks the inbound sub-property.

Root Cause

In bot.ts:737, the expression channelRuntime ?? getFeishuRuntime().channel selects channelRuntime when truthy, even if it is a partial object without inbound. The ChannelGatewayContext.channelRuntime type is ChannelRuntimeSurface (only guarantees runtimeContexts), but channel.ts:1326 casts it to PluginRuntime["channel"] via as PluginRuntime["channel"]. When a partial runtime object without inbound reaches the handler, the unsound type assertion becomes a runtime crash at core.channel.inbound.run().

Fix

Check channelRuntime?.inbound before using it; when inbound is absent, fall back to getFeishuRuntime().channel which always provides the full runtime surface.

-      channel: channelRuntime ?? getFeishuRuntime().channel,
+      channel: channelRuntime?.inbound ? channelRuntime : getFeishuRuntime().channel,

Real behavior proof

Behavior or issue addressed: Feishu channel dispatch no longer crashes with TypeError when channelRuntime lacks the inbound property.

Real environment tested: Linux (WSL2), Node v24.16.0, commit 9725989.

Exact steps or command run after this patch: Verified the fix by checking the code change ensures channelRuntime?.inbound is truthy before using channelRuntime, otherwise falls back to getFeishuRuntime().channel.

Evidence after fix: Terminal output from code inspection:

$ grep -n "channelRuntime?.inbound" extensions/feishu/src/bot.ts
737:      channel: channelRuntime?.inbound ? channelRuntime : getFeishuRuntime().channel,

The conditional channelRuntime?.inbound ? channelRuntime : getFeishuRuntime().channel ensures:

  • If channelRuntime has inbound → uses channelRuntime (same behavior as before)
  • If channelRuntime is falsy or lacks inbound → falls back to getFeishuRuntime().channel (always has inbound)

Observed result after fix: The crash path is eliminated by falling back to the registered runtime when inbound is absent. The working path (when channelRuntime has inbound) is unchanged. This is a purely defensive guard.

What was not tested: Actual Feishu channel runtime behavior with partial channelRuntime objects in production; the fix is based on code analysis of the type mismatch.

Change Type

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Security Impact

  • No new permissions/capabilities
  • No secrets/tokens handling changed
  • No new/changed network calls
  • No command/tool execution surface changed
  • No data access scope changed

Compatibility

  • Backward compatible — guard only expands the fallback path
  • No config/env changes
  • No migration needed

Fixes #93453

When the gateway provides a partial channelRuntime object without the
inbound sub-property, the dispatch path crashes with TypeError: Cannot
read properties of undefined (reading 'run') because the nullish
coalescing operator selects the partial object over the safe fallback.

Check channelRuntime?.inbound before using it; when inbound is absent,
fall back to getFeishuRuntime().channel which always provides the full
runtime surface including inbound.run().

Fixes openclaw#93453
@openclaw-barnacle openclaw-barnacle Bot added channel: feishu Channel integration: feishu size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 16, 2026
@clawsweeper

clawsweeper Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper review: did not complete due to Codex infrastructure failure. Reviewed June 15, 2026, 11:28 PM ET / 03:28 UTC.

Summary
Review failed before ClawSweeper could summarize the requested change.

PR surface: Source 0. Total 0 across 1 file.

Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path.

Review metrics: none identified.

Merge readiness
Not assessed.
Failure reason: invalid structured output.

This is a ClawSweeper/Codex infrastructure failure, not a PR readiness or patch-quality verdict.
Keep any merge decision on the normal maintainer review path until ClawSweeper can complete a fresh review.

Risk before merge

  • [P1] No close action taken because the review did not complete.

Maintainer options:

  1. Decide the mitigation before merge
    Retry the Codex review after fixing the execution failure.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • Review did not complete, so no work-lane recommendation was made.
Review details

Best possible solution:

Retry the Codex review after fixing the execution failure.

Do we have a high-confidence way to reproduce the issue?

Unclear. The review failed before ClawSweeper could establish a reproduction path.

Is this the best way to solve the issue?

Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction.

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model internal, reasoning high; reviewed against 67c80e941ecf.

Evidence reviewed

PR surface:

Source 0. Total 0 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 1 1 0
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 1 1 0

What I checked:

  • failure reason: invalid structured output.
  • codex failure detail: Codex review failed for this PR with exit 0 and wrote invalid JSON or schema-invalid output to /home/runner/work/clawsweeper/clawsweeper/artifacts/event/codex/93472.json: decision.rootCauseCluster.currentItemRelationship fixed_by_candidate requires a canonical PR.
  • codex stderr: No stderr captured.
  • codex stdout: d":true,"automergeInstruction":""},{"title":"Choose One Canonical PR","body":"If maintainers prefer the identical guard in [AI] fix(feishu): guard against missing inbound in channelRuntime fallback #93466 or the broader optional-runtime repair in #92595: fix(feishu): handle uninitialized runtime gracefully on inbound messages #92975, pause this PR until the canonical path is proof-positive.","category":"pause_or_close","recommended":false,"automergeInstruction":""},{"title":"Accept Hotfix Risk","body":"Maintainers may choose to land the one-line fallback as an urgent low-code-risk hotfix while separately tracking live Feishu proof and duplicate cleanup.","category":"accept_risk","recommended":false,"automergeInstruction":""}],"reviewMetrics":[],"labelJustifications":[{"label":"P1","reason":"The linked regression can make Feishu inbound messages fail before agent dispatch for affected users."},{"label":"merge-risk: 🚨 message-delivery","reason.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)
How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@sliverp sliverp self-assigned this Jun 16, 2026
@sliverp

sliverp commented Jun 16, 2026

Copy link
Copy Markdown
Member

checking~

@sliverp

sliverp commented Jun 16, 2026

Copy link
Copy Markdown
Member

Thanks for the focused fix. The fallback shape looks right, but this PR should include a narrow regression test for the exact missing case before merge.

Please add a test that calls the Feishu message handling path with a truthy partial channelRuntime that has runtimeContexts but no inbound, then verifies dispatch does not crash and falls back to the full Feishu runtime's channel.inbound.run. That is the runtime shape described in #93453 and is the behavior this one-line guard is protecting.

The focused local proof I ran was:

node scripts/run-vitest.mjs extensions/feishu/src/bot.test.ts
Test Files 1 passed (1)
Tests 82 passed (82)

So this is not a request for broad coverage, just the missing regression case for the reported crash path.

@sliverp

sliverp commented Jun 16, 2026

Copy link
Copy Markdown
Member

I rechecked the earlier closed reports and this should be framed as a recurrence of the same symptom after the month-start fix, not as an isolated first-time bug.

Earlier reports such as #88863 / #88889 / #89697 were closed because main had d05e4a4bc6f (fix(feishu): use full gateway channel runtime). That fix addressed the old release path where Feishu did not receive the gateway-owned channel runtime at all. It threaded ctx.channelRuntime through channel.ts -> monitor.ts -> monitor.account.ts -> handleFeishuMessage.

#93453 is different because it reports 2026.6.6, and v2026.6.6 already contains that runtime plumbing. The remaining gap is that ChannelGatewayContext.channelRuntime is typed as the public ChannelRuntimeSurface, which only guarantees runtimeContexts, while extensions/feishu/src/channel.ts casts it to PluginRuntime["channel"]. If a truthy context-only runtime reaches bot.ts, the old channelRuntime ?? getFeishuRuntime().channel still chooses it and bypasses the full fallback, so core.channel.inbound.run can still be undefined.

So the needed regression test is specifically the second-order case after d05e4a4bc6f: pass a truthy partial channelRuntime with runtimeContexts but no inbound, and verify Feishu falls back to getFeishuRuntime().channel and dispatch does not crash.

There is already a sibling PR, #93466, with the same guard plus this regression test (falls back to full runtime channel when partial channelRuntime lacks inbound). Either this PR should add equivalent coverage and mention the d05e4a4bc6f history, or maintainers should pick #93466 as the canonical fix.

I would not use #93483 as-is for this specific failure mode: spreading the full plugin runtime does not help if the code still overrides channel with a partial channelRuntime that lacks inbound.

Add a test verifying that handleFeishuMessage correctly falls back to
getFeishuRuntime().channel when the gateway provides a partial
channelRuntime object without the inbound sub-property.

Covers the fix in openclaw#93472 for issue openclaw#93453.
@xzh-icenter

Copy link
Copy Markdown
Contributor Author

@sliverp Thank you! The test has been added. Please have a look when you get a chance.

@xzh-icenter

Copy link
Copy Markdown
Contributor Author

93466 has merged

xzh-icenter added a commit to xzh-icenter/openclaw that referenced this pull request Jun 16, 2026
Add a test verifying that handleFeishuMessage correctly falls back to
getFeishuRuntime().channel when the gateway provides a partial
channelRuntime object without the inbound sub-property.

Covers the fix in openclaw#93472 for issue openclaw#93453.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu proof: supplied External PR includes structured after-fix real behavior proof. size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: feishu channel: failed to dispatch message — TypeError: Cannot read properties of undefined (reading 'run')

2 participants