Skip to content

fix(feishu): auto-convert local image path text to image message in outbound#29264

Merged
Takhoffman merged 3 commits intoopenclaw:mainfrom
paceyw:fix/feishu-local-image-path-autoupload
Feb 28, 2026
Merged

fix(feishu): auto-convert local image path text to image message in outbound#29264
Takhoffman merged 3 commits intoopenclaw:mainfrom
paceyw:fix/feishu-local-image-path-autoupload

Conversation

@paceyw
Copy link
Copy Markdown
Contributor

@paceyw paceyw commented Feb 28, 2026

Problem

When upstream agent output accidentally contains a local image path string, Feishu outbound sendText sends it as plain text, so users see a local file path instead of an image.

Root Cause

No compatibility conversion exists in Feishu outbound text path. Only sendMedia path handles upload + image send.

Fix (Scheme A)

In extensions/feishu/src/outbound.ts:

  • Add normalizePossibleLocalImagePath(text) guard
  • In sendText, detect path-like local image payload and route to sendMediaFeishu
  • Keep fallback to original sendMessageFeishu on failure

Why this approach

  • Minimal and safe hotfix scope
  • Immediate mitigation without upstream protocol migration
  • Preserves backward compatibility

Validation checklist

  • Plain text messages unchanged
  • Local absolute image path routes to image send path
  • Non-image/local-invalid paths remain text
  • Upload failure falls back to text without blocking delivery

Notes

This addresses runtime behavior where local file path text could leak to Feishu chat. It does not replace long-term protocol governance (structured image output), which can be handled in a follow-up.

@openclaw-barnacle openclaw-barnacle bot added channel: feishu Channel integration: feishu size: XS labels Feb 28, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 28, 2026

Greptile Summary

Adds auto-detection of local image paths in text messages and routes them to image upload instead of sending as plain text.

  • Implemented normalizePossibleLocalImagePath() helper with validation for absolute paths, image extensions, and file existence
  • Modified sendText to detect local image paths and route to sendMediaFeishu, with graceful fallback to text on failure
  • Found one race condition bug between file existence check and stat call that could throw uncaught errors

Confidence Score: 3/5

  • Safe to merge after fixing the race condition error handling issue
  • The implementation approach is sound and includes proper fallback handling, but there's a logic bug where fs.statSync can throw an uncaught error if the file is deleted or becomes inaccessible between the existsSync and statSync calls. Once this error handling is fixed, the change should be safe to merge.
  • extensions/feishu/src/outbound.ts needs the race condition fix before merging

Last reviewed commit: b18cf02

Copy link
Copy Markdown
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.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +25 to +26
if (!fs.existsSync(raw)) return null;
if (!fs.statSync(raw).isFile()) return null;
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.

Race condition: if file is deleted between existsSync and statSync, this will throw an uncaught error.

Suggested change
if (!fs.existsSync(raw)) return null;
if (!fs.statSync(raw).isFile()) return null;
try {
const stats = fs.statSync(raw);
if (!stats.isFile()) return null;
} catch {
return null;
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/outbound.ts
Line: 25-26

Comment:
Race condition: if file is deleted between `existsSync` and `statSync`, this will throw an uncaught error.

```suggestion
  try {
    const stats = fs.statSync(raw);
    if (!stats.isFile()) return null;
  } catch {
    return null;
  }
```

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

Copy link
Copy Markdown

@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: b18cf02223

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +14 to +15
const hasWhitespace = /\s/.test(raw);
if (hasWhitespace) return null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle local image paths that contain spaces

The new auto-conversion path exits early on any whitespace, so valid local image paths like /Users/.../My File.png are never converted and still leak as plain text. This is a real behavior gap because the codebase already treats space-containing absolute paths as valid media inputs (e.g., src/media/parse.test.ts covers /Users/pete/My File.png), so common screenshot-style filenames won’t benefit from this hotfix.

Useful? React with 👍 / 👎.

paceyw and others added 3 commits February 27, 2026 21:16
- Add try-catch around fs.statSync to handle file deletion between existsSync and statSync
- Fix oxfmt formatting issues
@Takhoffman Takhoffman force-pushed the fix/feishu-local-image-path-autoupload branch from 6e66b9d to 14cad1e Compare February 28, 2026 03:28
@Takhoffman Takhoffman merged commit 0e4c24e into openclaw:main Feb 28, 2026
13 checks passed
@Takhoffman
Copy link
Copy Markdown
Contributor

PR #29264 - fix(feishu): auto-convert local image path text to image message in outbound (#29264)

Merged via squash.

  • Merge commit: 0e4c24e
  • Verified: pnpm build, pnpm check, pnpm test:macmini
  • Changes made:
    A\textensions/feishu/src/outbound.test.ts
  • Why these changes were made:
    The PR introduced local-image auto-conversion in Feishu outbound text send path without regression coverage, so tests were added to cover conversion, non-conversion, and fallback behavior.
  • Changelog: CHANGELOG.md updated=true required=true opt_out=false

Thanks @paceyw!

Copy link
Copy Markdown

@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: 14cad1e14a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +56 to +58
mediaUrl: localImagePath,
accountId: accountId ?? undefined,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Forward mediaLocalRoots in sendText auto-conversion

The new sendText auto-conversion path calls sendMediaFeishu without forwarding mediaLocalRoots, unlike the normal sendMedia branch. In contexts where outbound delivery provides scoped roots (for example agent workspace files), loadWebMedia will evaluate the path against default roots and reject common workspace-* paths, causing this conversion to fail and fall back to sending the raw file path text. That means the hotfix silently does not work for trusted local image paths produced in scoped workspaces.

Useful? React with 👍 / 👎.

r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
mylukin pushed a commit to mylukin/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 2fcfe04)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 2fcfe04)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 2fcfe04)
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
newtontech pushed a commit to newtontech/openclaw-fork that referenced this pull request Feb 28, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Mar 1, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Mar 1, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
ansh pushed a commit to vibecode/openclaw that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
safzanpirani pushed a commit to safzanpirani/clawdbot that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
venjiang pushed a commit to venjiang/openclaw that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
sachinkundu pushed a commit to sachinkundu/openclaw that referenced this pull request Mar 6, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 15, 2026
…utbound (openclaw#29264) thanks @paceyw

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: paceyw <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 0e4c24e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants