Skip to content

fix #92246: QQ Bot C2C: Media sending (image/file) returns 400 Bad Request#92747

Closed
zhangguiping-xydt wants to merge 5 commits into
openclaw:mainfrom
zhangguiping-xydt:feat/issue-92246
Closed

fix #92246: QQ Bot C2C: Media sending (image/file) returns 400 Bad Request#92747
zhangguiping-xydt wants to merge 5 commits into
openclaw:mainfrom
zhangguiping-xydt:feat/issue-92246

Conversation

@zhangguiping-xydt

@zhangguiping-xydt zhangguiping-xydt commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix classification: root-cause fix.
  • Root cause: QQBot C2C image/file byte sources were routed through the one-shot /files file_data upload contract, while QQ's C2C image/file path accepts these bytes through the chunked upload contract; the channel adapter also normalized lower-layer QQ upload failures into empty successful receipts.
  • Why this is root-cause fix: the unified sender now routes every C2C image/file byte source covered by the issue shape — URL downloads, base64/data sources, buffers, and local files — through the existing upload_prepare -> COS PUT -> upload_part_finish -> /files chunked contract before /messages, so the failing upload contract is no longer used for C2C image/file delivery. The adapter also preserves the delivery invariant that a successful generic send must include a QQ platform message id.
  • Why it matters / User impact: users sending image or file content to QQ private chats no longer get a misleading successful OpenClaw result while QQ rejected the upload with HTTP 400.
  • What did NOT change: this PR only changes QQBot C2C image/file upload routing and generic QQBot send error propagation; group media, voice/video routing, public config, schema, migrations, and channel APIs remain unchanged.
  • Architecture / source-of-truth check: the source-of-truth boundary is the existing QQBot unified sender dispatch and QQ upload contract selection; no public API/config/schema contract is expanded, and SSRF validation remains at OpenClaw's guarded URL downloader before any QQ upload. Same-contract related open PR scan found no open PR matching QQBot C2C media Bad Request / upload_prepare / image-file Bad Request queries.
  • Patch quality notes: the diff is intentionally limited to QQBot sender routing, adapter result normalization, and regression tests; no unrelated refactor or fallback path was added.
  • Review focus: the C2C image/file branch in the unified sender, especially the URL/base64/buffer/localPath source routing, and the generic message adapter's error/empty-receipt handling.

Linked context

Closes #92246

Related #92246

Was this requested by a maintainer or owner? No maintainer request found; this follows the issue report and reproduces the reported C2C image/file failure path.

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: QQBot C2C image/file sends through the generic message path returned QQ API HTTP 400 during media upload while OpenClaw could still surface an empty successful receipt.

  • Real environment tested: a live QQBot app and a real C2C private-chat target captured from C2C_MESSAGE_CREATE; credentials, target openid, token, file_info, and COS presigned URLs were redacted.

  • Exact steps or command run after this patch:

    1. Start QQBot gateway capture, receive a private C2C message from the tester, and capture the C2C target from the gateway event.
    2. Use the fixed branch's QQBot unified sender to send a URL image to that C2C target.
    3. Use the fixed branch's QQBot unified sender to send a URL file to that C2C target.
  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):

    Live QQBot C2C send proof, redacted:

    QQBot live proof runner started {"mode":"send-after","appId":"1904…7531"}
    QQBot live proof: sending fixed-branch C2C URL image via unified sender {"target":"qqbot:c2c:<redacted-c2c-openid>","imageUrl":"https://raw.githubusercontent.com/openclaw/openclaw/main/docs/assets/openclaw-logo-text.png"}
    [qqbot:chunked-upload] Start: file=file size=90.0KB type=1
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/upload_prepare (timeout: 120000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: 8c4a5a8c29c0f611149737cae1fa84ed
    [qqbot:chunked-upload] prepared: upload_id=upload_1781369239324697480_817037 block=90.0KB parts=1 concurrency=1
    [qqbot:chunked-upload] PUT part 1/1 OK (665ms ETag="c5032c050540994cd223c6b968d41dce" requestId=NmEyZDg5OTdfNjJiNjNlMDlfM2UwYV9hM2U0MDRl)
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/upload_part_finish (timeout: 120000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: 172a96e34f0c05d2311844a610bfc192
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/files (timeout: 120000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: 064738ff19dfd634e6adff4c5f48b794
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/messages (timeout: 30000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: b7b68978da7a43206c606728bc6cd1db
    QQBot live proof: image delivered {"messageId":"ROBOT1.0_SXtbE0cfdw9aiRPIzChuFsts3EWynm.-tswmoKvO4fYxqzrtv9K41PPYD.TG9JA-5knGWIyA0hFu7MXIaP-0tw!!"}
    
    QQBot live proof: sending fixed-branch C2C URL file via unified sender {"target":"qqbot:c2c:<redacted-c2c-openid>","fileUrl":"https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/codespell-ignore.txt"}
    [qqbot:chunked-upload] Start: file=openclaw-92246-live-proof.txt size=82B type=4
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/upload_prepare (timeout: 120000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: 9e0bef2ab3f2385c224c8cccbee48740
    [qqbot:chunked-upload] PUT part 1/1 OK (354ms ETag="31a040cdd946e9588eebcd0045d2e400" requestId=NmEyZDg5OWRfYzY4ZTI3MDlfNTgyMV8xMmMyZmFhOQ==)
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/upload_part_finish (timeout: 120000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: ba3885e777563e6361a793c15961afe0
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/files (timeout: 120000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: e3cb27e84fd28609eaa569505eac18ad
    [qqbot:api] >>> POST https://api.sgroup.qq.com/v2/users/<redacted-c2c-openid>/messages (timeout: 30000ms)
    [qqbot:api] <<< Status: 200 OK | TraceId: 637a4895101c5ea37e0e21cec1ed997c
    QQBot live proof: file delivered {"messageId":"ROBOT1.0_SXtbE0cfdw9aiRPIzChuFh6tpXoB-GQCtfGhwebmWhkTli-JKMYD81YPMRU9qIDB5knGWIyA0hFu7MXIaP-0tw!!"}
    
  • Observed result after fix: both live C2C URL image and URL file sends completed the chunked upload sequence and returned non-empty QQ message ids from /messages.

  • What was not tested: group media sends, voice/video media sends, and QQ client UI screenshot capture from this environment.

  • Proof limitations or environment constraints: I could verify the live QQBot API path and returned message ids, but I do not have direct access to the tester's QQ client UI in this coding environment, so I did not attach a QQ client screenshot here. The non-URL C2C byte-source extension is covered by focused sender regressions because the same chunked uploader contract is exercised by the live URL proof.

  • Before evidence (optional but encouraged): the issue report shows the previous C2C media upload path failing with API Error [/v2/users/{openid}/files]: Bad Request / HTTP 400. The new sender regression failed before the expanded implementation for C2C base64, buffer, and localPath image sources because each still called MediaApi.uploadMedia one-shot file_data; the adapter regression also failed before the implementation because a lower-layer QQ upload error could resolve as an empty successful receipt.

Tests and validation

Which commands did you run?

Validation `sender-byte-sources-red` (expected fail before expansion, exit_code=1):
Test Files  1 failed (1)
Tests       3 failed | 2 passed (5)
Failure: C2C image base64, buffer, and localPath sources still called MediaApi.uploadMedia one-shot file_data.

Validation `sender-byte-sources-green` (pass, exit_code=0):
Test Files  1 passed (1)
Tests       5 passed (5)

Validation `qqbot-focused-all-sources` (pass, exit_code=0):
Test Files  3 passed (3)
Tests       27 passed (27)

Validation `extensions-test-typecheck-all-sources` (pass, exit_code=0):
node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo

Validation `check-lint-all-sources` (pass, exit_code=0):
node scripts/run-oxlint-shards.mjs --threads=8

Validation `bundled-extension-lint-all-sources` (pass, exit_code=0):
node scripts/run-bundled-extension-oxlint.mjs

What regression coverage was added or updated?

  • Added sender-level coverage proving C2C URL image/file bytes are fetched through the guarded URL downloader and then uploaded with ChunkedMediaApi.uploadChunked, not MediaApi.uploadMedia one-shot file_data.
  • Added sender-level coverage proving C2C base64, buffer, and localPath image byte sources also use ChunkedMediaApi.uploadChunked instead of the one-shot file_data path.
  • Added generic message adapter coverage proving media sends reject when the QQ outbound layer returns an API error.
  • Kept low-level media API coverage that remote URLs are not passed through to QQ upload bodies.

What failed before this fix, if known?

  • The original sender regression failed before the implementation because C2C URL image/file sends used the one-shot file_data upload path.
  • The expanded sender regression failed before the follow-up implementation because C2C base64, buffer, and localPath image sources still used the one-shot file_data upload path.
  • The adapter regression failed before the implementation because a lower-layer QQ upload error could resolve as an empty successful receipt.
  • Remote CI check-lint and check-additional-extension-bundled failed on the no-op String(...) conversion in the QQBot channel adapter; the conversion was removed and both corresponding local lint commands now pass.

If no test was added, why not? Regression tests were added.

Risk checklist

Did user-visible behavior change? (Yes/No)

Yes. C2C image/file sends should now succeed via QQ's chunked upload path for URL/base64/buffer/localPath byte sources, and failed QQ media sends now reject instead of returning an empty success.

Did config, environment, or migration behavior change? (Yes/No)

No.

Did security, auth, secrets, network, or tool execution behavior change? (Yes/No)

Yes, network behavior changes narrowly for QQBot C2C image/file sends: bytes now use the existing chunked upload flow. Remote URL fetches still go through the existing SSRF-guarded downloader, local files still go through the existing safe-open path, and this PR does not expose secrets or add config.

What is the highest-risk area?

The highest-risk area is QQBot media upload routing for C2C image/file byte sources.

How is that risk mitigated?

The change is scoped to C2C image/file sources, reuses the existing chunked upload implementation, preserves guarded URL download and safe local-file handling, adds focused regression tests for URL/base64/buffer/localPath sources, passes typecheck/lint, and was verified against a live QQBot C2C target for URL image and URL file delivery.

Current review state

What is the next action?

Ready for maintainer review after updated CI settles.

What is still waiting on author, maintainer, CI, or external proof?

Waiting on updated CI and maintainer review. A QQ client UI screenshot can be added later if the tester shares one, but live QQBot API proof for image and file delivery is included above.

Which bot or reviewer comments were addressed?

  • RF-001 (status: waiting on author label): author-side follow-up was completed in this update; the label should be cleared by maintainer/bot once updated checks/review state are accepted.
  • RF-002 (P1 source coverage): fixed by routing C2C image/file base64, buffer, and localPath byte sources through chunked upload instead of one-shot file_data.
  • RF-003 (P1 failing CI checks): fixed by removing the redundant String(...) conversion and re-running the two corresponding local lint commands successfully.
  • RF-004 (P2 maintainer scope concern): addressed by expanding the PR from URL-only to all reported C2C image/file byte-source shapes while keeping group media/config/schema/API out of scope.
  • RF-005 (P2 sender.ts source branch): fixed in the unified sender dispatch; new regressions cover URL/base64/buffer/localPath C2C image/file routing through the chunked uploader.
  • RF-006 (P3 no-op conversion): fixed in the QQBot channel adapter.

@openclaw-barnacle openclaw-barnacle Bot added channel: qqbot size: M proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 13, 2026
@clawsweeper

clawsweeper Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 13, 2026, 2:11 PM ET / 18:11 UTC.

Summary
The PR changes QQBot C2C image/file upload routing to use the chunked upload flow for URL, base64, buffer, and local-path byte sources, adds error propagation for empty/error media receipts, and adds focused regression tests.

PR surface: Source +21, Tests +243. Total +264 across 5 files.

Reproducibility: no. independent high-confidence live reproduction by this review. Source inspection plus the linked issue logs show the old one-shot C2C media upload path, and the PR supplies redacted live after-fix QQBot logs.

Review metrics: 1 noteworthy metric.

  • Reported C2C source coverage: 4 covered, 0 left unhandled. The prior blocker was incomplete handling for URL, base64, buffer, and local-path image/file sends named by the linked issue.

Stored data model
Persistent data-model change detected: persistent cache schema: extensions/qqbot/src/engine/messaging/sender.test.ts, serialized state: extensions/qqbot/src/engine/messaging/sender.test.ts. Confirm migration or upgrade compatibility proof before merge.

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:

  • none.

Next step before merge

  • No automated repair is needed because the earlier concrete blockers appear addressed; the remaining action is normal maintainer review and check completion.

Security
Cleared: No concrete security or supply-chain regression was found; the diff adds no dependencies, workflows, secrets handling, or new unguarded remote fetch path.

Review details

Best possible solution:

Land a focused QQBot plugin repair after maintainer review and required checks, keeping the fix inside the existing sender/upload boundary without adding config or channel API surface.

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

No independent high-confidence live reproduction by this review. Source inspection plus the linked issue logs show the old one-shot C2C media upload path, and the PR supplies redacted live after-fix QQBot logs.

Is this the best way to solve the issue?

Yes; the updated patch uses the existing QQBot sender dispatch and chunked uploader rather than adding a new tool, config option, or API, and it now covers the previously missed source shapes.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes redacted live QQBot C2C logs showing after-fix URL image and file sends complete the chunked upload sequence and return non-empty QQ message IDs.
  • 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 (logs): The PR body includes redacted live QQBot C2C logs showing after-fix URL image and file sends complete the chunked upload sequence and return non-empty QQ message IDs.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: This PR targets a real QQ private-chat media delivery bug with limited blast radius to QQBot C2C image/file sends.
  • 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 (logs): The PR body includes redacted live QQBot C2C logs showing after-fix URL image and file sends complete the chunked upload sequence and return non-empty QQ message IDs.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes redacted live QQBot C2C logs showing after-fix URL image and file sends complete the chunked upload sequence and return non-empty QQ message IDs.
Evidence reviewed

PR surface:

Source +21, Tests +243. Total +264 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 2 35 14 +21
Tests 3 254 11 +243
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 289 25 +264

What I checked:

  • Repository policy read: Root and scoped extension review policies were read fully; the plugin-boundary and deep-review guidance apply because the diff is confined to extensions/qqbot. (AGENTS.md:1, ca2410ab072e)
  • Current main reproduces the old routing shape: Current main dispatches C2C URL/base64 and small localPath/buffer media through the one-shot MediaApi.uploadMedia path, matching the linked issue’s reported failing upload contract. (extensions/qqbot/src/engine/messaging/sender.ts:659, ca2410ab072e)
  • PR routes reported C2C image/file sources through chunked upload: The updated PR adds requiresC2CChunkedUpload and applies it to URL, base64, localPath, and buffer branches for C2C image/file sends. (extensions/qqbot/src/engine/messaging/sender.ts:637, bb99be49207f)
  • Regression coverage covers the previous source-shape gap: The new sender tests assert URL image/file and base64, buffer, and localPath C2C image sources call ChunkedMediaApi.uploadChunked instead of MediaApi.uploadMedia. (extensions/qqbot/src/engine/messaging/sender.test.ts:64, bb99be49207f)
  • Adapter empty-success behavior is addressed: The PR changes toQQBotMessageSendResult so QQ outbound errors or missing platform message IDs throw instead of returning an empty successful receipt. (extensions/qqbot/src/channel.ts:136, bb99be49207f)
  • Real behavior proof supplied: The PR body includes redacted live QQBot C2C logs showing URL image and URL file sends completing upload_prepare, COS PUT, upload_part_finish, /files, and /messages with non-empty QQ message IDs. (bb99be49207f)

Likely related people:

  • Vincent Koc: git blame and git show attribute the current QQBot media sender, one-shot media API, and chunked upload files to commit 2d2c1e63f0da9356c09f0a4c2a5e227f321ab9f3. (role: current main source author; confidence: high; commits: 2d2c1e63f0da; files: extensions/qqbot/src/engine/messaging/sender.ts, extensions/qqbot/src/engine/api/media.ts, extensions/qqbot/src/engine/api/media-chunked.ts)
  • cxyhhhhh: Merged PR https://github.com/openclaw/openclaw/pull/70624 introduced the QQBot group/C2C streaming and chunked media upload refactor that owns the chunked upload path this PR reuses. (role: feature author in merged PR history; confidence: medium; commits: 5ccf179a34a9; files: extensions/qqbot/src/engine/api/media-chunked.ts, extensions/qqbot/src/engine/messaging/sender.ts, extensions/qqbot/src/engine/messaging/outbound-media-send.ts)
  • sliverp: Merged PR https://github.com/openclaw/openclaw/pull/52986 added the original QQBot plugin and media/channel surfaces, making this a useful adjacent routing candidate. (role: original plugin author in merged PR history; confidence: medium; commits: bf6f506dfae6; files: extensions/qqbot/src/channel.ts, extensions/qqbot/src/outbound.ts, extensions/qqbot/src/api.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.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. labels Jun 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 13, 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 rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 13, 2026
@zhangguiping-xydt

zhangguiping-xydt commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

Additional QQ client UI proof for #92246:
qqbot

@vincentkoc vincentkoc self-assigned this Jun 14, 2026
@vincentkoc

Copy link
Copy Markdown
Member

closing this because the broad C2C routing change is not supported by the current QQ contract or live proof.

QQ's official rich-media contract documents /v2/users/{openid}/files with both url and base64 file_data for C2C image/file uploads: https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/send-receive/rich-media.html

This PR instead forces every C2C image/file source through the chunked upload path based only on generic HTTP 400 reports, without the rejected response body/error code or a live before/after proof. That can move all small C2C media onto a different quota/failure surface while bypassing the documented one-shot path. The adapter error-propagation improvement is useful, but it should be a separate bounded fix; the upload-route change is too speculative to land.

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

Labels

channel: qqbot P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M 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.

QQ Bot C2C: Media sending (image/file) returns 400 Bad Request

2 participants