#18811: fix(media): require file extension for ambiguous MEDIA: path detection
size: XS
trusted-contributor
Cluster:
Media Handling Improvements
## Summary
Fixes #18780 — `MEDIA:` substrings in tool result text (e.g. from `web_fetch` of release notes) trigger false-positive file path detection, causing ENOENT errors on Telegram and other channels.
## Root Cause
`isLikelyLocalPath()` in `src/media/parse.ts` has a catch-all condition that matches **any** string containing a `/` character:
```ts
!SCHEME_RE.test(candidate) && (candidate.includes('/') || candidate.includes('\\'))
```
When a line starts with `MEDIA:` (e.g. `MEDIA:-prefixed paths (lenient whitespace) when loading...`), the text after the token contains `/` characters in prose, so `isLikelyLocalPath` returns `true`, and the handler tries to `fs.open()` the prose as a file path.
## Fix
Add `HAS_FILE_EXT.test(candidate)` to the catch-all condition. This requires a file extension (`.ext`) for ambiguous relative paths like `subdir/file.png`. All explicit path prefixes (`/`, `./`, `../`, `~`, Windows drives, UNC) are checked by earlier conditions and remain unaffected.
## Tests
- Added regression test for the exact scenario from #18780
- All existing media/parse tests pass (15/15)
- All outbound/delivery tests pass (564/564)
- All tools media tests pass (30/30)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixes false-positive `MEDIA:` path detection by adding a file extension requirement (`HAS_FILE_EXT.test()`) to the catch-all condition in `isLikelyLocalPath()`. This prevents prose text containing `/` characters from being treated as file paths when it appears after a `MEDIA:` token.
- The code fix in `src/media/parse.ts` is correct and well-scoped — it only tightens the catch-all condition for ambiguous relative paths (those without explicit prefixes like `/`, `./`, `../`, `~`, drive letters, or UNC). All explicitly-prefixed paths are unaffected.
- The regression test in `src/media/parse.test.ts` has a gap: the test string contains no `/` or `\` characters, so the catch-all condition would never have fired for this input even before the fix. The test passes on both old and new code and doesn't validate the `HAS_FILE_EXT` guard. The test input should include `/` in the prose to properly exercise the changed code path.
<h3>Confidence Score: 4/5</h3>
- The code fix is correct and safe to merge, though the regression test should be strengthened to actually exercise the fix.
- The production code change is minimal, well-commented, and correctly addresses the bug. It reuses an existing regex (`HAS_FILE_EXT`) that is already battle-tested in the same file. All explicit path prefix handling is unaffected. The only concern is the regression test doesn't actually validate the fix — the test string lacks `/` characters needed to trigger the catch-all condition. This means the fix could regress without the test catching it. Deducting one point for this test gap.
- `src/media/parse.test.ts` — the regression test should include `/` characters in the prose to properly exercise the `HAS_FILE_EXT` guard on the catch-all condition.
<sub>Last reviewed commit: 346d480</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#14794: fix: parse inline MEDIA: tokens in agent replies
by explainanalyze · 2026-02-12
86.2%
#18890: fix(media): parse tool-result MEDIA directives with shared parser
by teededung · 2026-02-17
86.1%
#19868: fix: prevent media token regex from matching markdown bold text
by sanketgautam · 2026-02-18
85.2%
#9817: fix(media): resolve relative paths before reading local files (#8759)
by lailoo · 2026-02-05
83.8%
#19399: telegram: fix MEDIA false positives and partial final drop
by HOYALIM · 2026-02-17
82.0%
#22356: test(web): fix media test fixture local root handling
by AIflow-Labs · 2026-02-21
79.2%
#7400: media: allow temp-dir MEDIA paths for tool outputs
by grammakov · 2026-02-02
78.6%
#16938: fix(media): reject unsupported URL schemes with clear error message
by zerone0x · 2026-02-15
78.4%
#22178: test(web): allow fixture roots in media local file tests
by Kansodata · 2026-02-20
78.4%
#21110: fix(tts): deliver audio via structured mediaUrl instead of MEDIA: t...
by hydro13 · 2026-02-19
78.2%