Skip to content

fix(discord): split encoded video URLs from captions#101815

Merged
steipete merged 2 commits into
openclaw:mainfrom
VectorPeak:fix/discord-encoded-video-url-split
Jul 9, 2026
Merged

fix(discord): split encoded video URLs from captions#101815
steipete merged 2 commits into
openclaw:mainfrom
VectorPeak:fix/discord-encoded-video-url-split

Conversation

@VectorPeak

@VectorPeak VectorPeak commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Discord sends captioned video media in two messages so the caption remains visible before the upload. The local video classifier checked the raw URL pathname, so a valid filename such as render%2Emp4 did not match the .mp4 suffix and incorrectly took the combined-send path.

Why This Change Was Made

The classifier now extracts and decodes only the final URL filename before extension matching. That matches the shared media loader's filename semantics while avoiding whole-path decoding: malformed escapes in earlier path segments cannot suppress classification, and encoded path delimiters are not reinterpreted as URL structure.

The original media URL is still passed unchanged into the existing guarded media loader and Discord send path.

User Impact

Captioned Discord videos whose filename contains percent-encoded extension characters now use the same caption-first/media-second delivery as ordinary .mp4, .mov, .webm, and other supported video URLs.

Evidence

  • Blacksmith Testbox coral-crab (tbx_01kx2dacsrr1z0hjxenejbt9s5): 55 focused tests passed across the direct media classifier and Discord outbound adapter.
  • Direct cases cover encoded dots and extension characters, malformed earlier path segments, encoded suffixes, double encoding, local query strings, and non-video extensions.
  • The outbound regression proves two sends and preserves the original encoded media URL.
  • Fresh autoreview after the maintainer refactor: no actionable findings, confidence 0.96.
  • git diff --check passed.

The existing PR runtime transcripts additionally exercise the production outbound adapter and real Discord send-stack body construction without claiming external network delivery.

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord size: XS triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. and removed triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 7, 2026
@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 7, 2026, 11:49 PM ET / 03:49 UTC.

Summary
The PR decodes Discord media URL pathnames before video-extension matching and adds an outbound adapter regression case for an encoded .mp4 URL.

PR surface: Source +4, Tests +13. Total +17 across 2 files.

Reproducibility: yes. for source-level reproduction: current main uses the raw URL pathname, and a render%2Emp4 pathname does not match the .mp4 suffix until decoded. I did not run a full live Discord send against current main.

Review metrics: none identified.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Rerun or resolve check-additional-boundaries-a before merging the exact head.

Risk before merge

  • [P1] Exact-head CI has check-additional-boundaries-a failing during setup with logs unavailable from gh run view; merge should wait for a rerun or maintainer confirmation that the failure is unrelated.

Maintainer options:

  1. Decide the mitigation before merge
    Land this focused Discord plugin fix after exact-head CI is clean, preserving original media URL pass-through and malformed-percent fallback behavior.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • No ClawSweeper repair is identified; maintainers should review the clean patch and resolve the failing CI shard before merge.

Security
Cleared: Cleared: the diff only changes local Discord extension detection plus a test, leaves the original mediaUrl passed into existing media loading policy, and does not touch dependencies, CI, secrets, or permissions.

Review details

Best possible solution:

Land this focused Discord plugin fix after exact-head CI is clean, preserving original media URL pass-through and malformed-percent fallback behavior.

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

Yes for source-level reproduction: current main uses the raw URL pathname, and a render%2Emp4 pathname does not match the .mp4 suffix until decoded. I did not run a full live Discord send against current main.

Is this the best way to solve the issue?

Yes; the PR fixes the Discord-owned classifier that gates this split, rather than changing shared media loading, and keeps the original URL flowing into the existing send path.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. Sufficient: the PR body includes copied terminal output from the real adapter path and local real Discord send-stack request construction showing caption-first/media-second behavior for the encoded-dot video case.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient: the PR body includes copied terminal output from the real adapter path and local real Discord send-stack request construction showing caption-first/media-second behavior for the encoded-dot video case.

Label justifications:

  • P2: This is a focused Discord outbound media bug with limited channel-specific blast radius.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient: the PR body includes copied terminal output from the real adapter path and local real Discord send-stack request construction showing caption-first/media-second behavior for the encoded-dot video case.
  • proof: sufficient: Contributor real behavior proof is sufficient. Sufficient: the PR body includes copied terminal output from the real adapter path and local real Discord send-stack request construction showing caption-first/media-second behavior for the encoded-dot video case.
Evidence reviewed

PR surface:

Source +4, Tests +13. Total +17 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 5 1 +4
Tests 1 15 2 +13
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 20 3 +17

What I checked:

  • Current main misses encoded dot suffixes: Current main normalizes URL media paths with parsed.pathname, and Node preserves %2E in new URL(...).pathname; the focused shell check showed the raw pathname does not end with .mp4 while decodeURIComponent(pathname) does. (extensions/discord/src/media-detection.ts:13, bf310355387d)
  • PR keeps the fix inside Discord media detection: At the PR head, the URL branch decodes parsed.pathname for suffix matching and falls back to the original pathname if decoding malformed percent escapes throws. (extensions/discord/src/media-detection.ts:14, 8583207945a2)
  • Outbound split decision is Discord-local: discordOutbound.sendMedia splits caption and media only when isLikelyDiscordVideoMedia(mediaUrl) is true, and the media send still passes the original mediaUrl through to sendMessageDiscord. (extensions/discord/src/outbound-adapter.ts:257, bf310355387d)
  • Regression coverage targets the edge case: The PR head adds an encoded URL extension case that expects two send calls and preserves the encoded URL in the media send options. (extensions/discord/src/outbound-adapter.test.ts:617, 8583207945a2)
  • Real behavior proof is present: The PR body includes copied terminal output showing the real outbound adapter path and a local real sendMessageDiscord media-stack run both produce caption-first/media-second calls for encoded-dot video media. (8583207945a2)
  • Feature history points to the Discord video split owners: History shows the Discord video media extension split was introduced in a62193c09ee654975ef760beb312670df8e4bc3e, then factored into media-detection.ts by b83ddf3cef7e1ce22423f46f2a4c64244cc04506 and touched by the current refactor in 7ff3f2dbf922d233bd8c86c6609f53185cf9f496. (extensions/discord/src/channel.ts:888, a62193c09ee6)

Likely related people:

  • steipete: Peter Steinberger introduced the Discord video caption/media split in a62193c09ee654975ef760beb312670df8e4bc3e, later extracted the media-detection helper in b83ddf3cef7e1ce22423f46f2a4c64244cc04506, and has the most sampled history on the Discord outbound/media files. (role: introduced behavior and heavy area contributor; confidence: high; commits: a62193c09ee6, b83ddf3cef7e, 43ef8a5a8657; files: extensions/discord/src/channel.ts, extensions/discord/src/media-detection.ts, extensions/discord/src/outbound-adapter.ts)
  • vincentkoc: Vincent Koc recently carried the Discord outbound adapter/media-detection files through release/refactor commits including e085fa1a3ffd32d0ea6917e1e6fb4ecbffbb77d2 and 7ff3f2dbf922d233bd8c86c6609f53185cf9f496. (role: recent area contributor; confidence: medium; commits: e085fa1a3ffd, 7ff3f2dbf922, 4d49c7b8a59e; files: extensions/discord/src/media-detection.ts, extensions/discord/src/outbound-adapter.ts, extensions/discord/src/outbound-adapter.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

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.
Review history (6 earlier review cycles)
  • reviewed 2026-07-07T17:00:52.017Z sha 5e5e22a :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-07T17:18:22.222Z sha 5e5e22a :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-07T17:26:23.000Z sha 5e5e22a :: needs maintainer review before merge. :: none
  • reviewed 2026-07-07T17:36:31.040Z sha ee34c67 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-07T17:42:38.668Z sha ee34c67 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-08T03:30:51.811Z sha e50c21e :: needs maintainer review before merge. :: none

@VectorPeak

Copy link
Copy Markdown
Contributor Author

/review

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 7, 2026
@VectorPeak

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Added production-path terminal proof to the PR body. It imports the real Discord outbound adapter, calls discordOutbound.sendMedia with https://cdn.discordapp.com/attachments/1/render%2Emp4?ex=1, and shows two observed send calls: caption first, then media with the original encoded URL.

Live Discord credentials are not available in this local environment, so the new proof is a redacted outbound-path transcript with injected final send transport rather than a live Discord network delivery screenshot.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 7, 2026
@VectorPeak

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Added a stronger non-live send-stack proof to the PR body. In addition to the existing outbound-adapter transcript, the new evidence drives the real \sendMessageDiscord\ media path with an encoded \ ile://.../render%2Emp4\ URL and captures the final Discord REST bodies before the network boundary: caption text first, then media upload body with
ender.mp4.

This is intentionally not claimed as live Discord network delivery; it is local runtime proof of the production outbound split plus real Discord send-stack body construction.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 8, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 8, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 8, 2026
@steipete steipete self-assigned this Jul 9, 2026
VectorPeak and others added 2 commits July 9, 2026 04:26
Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
@steipete
steipete force-pushed the fix/discord-encoded-video-url-split branch from 8583207 to c8febac Compare July 9, 2026 03:32
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Maintainer refactor and land-ready proof are complete on c8febac8cbbaf09ee158a2a1d95b5e40342abdba.

What changed:

  • rebased the contributor change into a clean two-commit stack;
  • narrowed decoding from the whole URL pathname to the final filename that owns extension semantics;
  • kept the original encoded URL unchanged for the guarded media loader and Discord send path;
  • added direct coverage for encoded extension characters, malformed earlier segments, encoded suffixes, double encoding, local paths, and non-video filenames;
  • retained an outbound regression proving caption-first/media-second delivery and original URL pass-through.

Proof:

  • Blacksmith Testbox coral-crab / tbx_01kx2dacsrr1z0hjxenejbt9s5:
    • pnpm test extensions/discord/src/media-detection.test.ts extensions/discord/src/outbound-adapter.test.ts — 55 passed;
    • pnpm check:changed — passed typechecks, core and extension lint, database-first, media-helper, runtime-sidecar, import-cycle, webhook-body, and pairing guards.
  • git diff --check — passed.
  • Fresh autoreview after the refactor — no actionable findings, confidence 0.96.

The PR's existing runtime transcripts additionally exercise the production adapter and real Discord send-stack body construction. No external Discord delivery is claimed or required for this filename-classification invariant.

@steipete
steipete merged commit 2cb482d into openclaw:main Jul 9, 2026
97 of 98 checks passed
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 9, 2026
* fix(discord): split encoded video URLs from captions

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>

* refactor(discord): scope media filename decoding

---------

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants