Skip to content

fix(slack): form-encode Web API requests - #3753

Open
nahyeongjin1 wants to merge 1 commit into
Yeachan-Heo:devfrom
nahyeongjin1:fix/slack-conversations-replies-form-encoding
Open

fix(slack): form-encode Web API requests#3753
nahyeongjin1 wants to merge 1 commit into
Yeachan-Heo:devfrom
nahyeongjin1:fix/slack-conversations-replies-form-encoding

Conversation

@nahyeongjin1

Copy link
Copy Markdown

What

  • Serialize Slack Web API POST parameters with URLSearchParams form encoding and omit undefined values.
  • Add regression coverage for conversations.replies, chat.postMessage, and optional thread_ts omission.
  • Document the user-facing fix under packages/coding-agent/CHANGELOG.mdUnreleased / Fixed.

Why

Slack's conversations.replies endpoint returns invalid_arguments for the JSON request body used by the live provider, while the equivalent form-encoded request succeeds. This prevents thread reconciliation during Slack notification startup.

Testing

  • bun test packages/coding-agent/test/sdk-slack-live-provider.test.ts packages/coding-agent/test/sdk-slack-daemon.test.ts — 60 pass, 221 assertions
  • bun --cwd=packages/coding-agent run check
  • bun run ci:test:smoke
  • bun run check — all adapter receipts completed, then the Telegram baseline manifest reported two missing commands; reproduced unchanged on pristine upstream/dev and still present after rebasing to caeeecbc with bun scripts/generate-telegram-baseline-manifest.ts --check:
    • notifications-telegram-daemon-staging-temp-leak.test.ts
    • notifications-topic-settle-fence-epoch.test.ts

GJC verdict

gajae.pr-review-verdict.v1 merge-approved sha256:93ce077c585a91bf61c378f16fdffc00d74aad0bd5024409037c292973284bc7 reviewer:critic evidence:local-focused-checks

  • Target branch is dev
  • bun check passes
  • Tested locally
  • CHANGELOG updated (if user-facing)
  • Verdict above matches the exact PR head, not an earlier commit

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Terminal red-team review at exact head a307d006764d5f502fc930831ff41b7392fd6249 (base dev caeeecbc52e5ff0f82e967c6c8f58d4c50d4f0da; base is the exact parent of head).

Scope reviewed: Slack Web API form encoding, headers/content types, Unicode and special parameters, pagination/thread/replies semantics, error handling, backward compatibility, and focused tests.

Implementation assessment: URLSearchParams correctly emits UTF-8 form data, omits undefined fields, preserves special characters, and leaves the existing conversations.history/conversations.replies lookup and error/retry semantics intact. Exact-head local evidence: bun test packages/coding-agent/test/sdk-slack-live-provider.test.ts — 11 pass; additional exact-head Unicode/special-parameter round-trip and content-type probe — pass.

REQUEST_CHANGES blocker: exact-head GitHub CI evidence is absent. The commit reports zero check runs and zero legacy statuses (check-runs: 0, commit status: pending, total_count: 0), and gh pr checks reports no checks for the branch. This prevents a MERGE_READY decision under the terminal review gate. Please produce green checks on this exact head or an explicitly recorded maintainer-approved CI waiver.

No source mutation or merge was performed. Signed via terminal GitHub CLI as Yeachan-Heo.

@nahyeongjin1
nahyeongjin1 force-pushed the fix/slack-conversations-replies-form-encoding branch from a307d00 to ba3a16a Compare August 3, 2026 00:21

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Fresh terminal GJC review at exact head ba3a16a095050514f66c807b3d9da5f60f6d0adf against current dev 57577acd7ea2da991024604e92bb209f3a30c7d5 (PR base recorded as bf37cb30d0442926ad3fb2b2c6fc26a6d3edeffc; current dev is two commits ahead of that base).

Adversarial scope: request serialization, auth/content-type semantics, Unicode/special/query edge cases, binary-body applicability, pagination/thread/replies behavior, error/retry compatibility, and regression coverage. The implementation uses URLSearchParams over the string-only Slack parameter contract, omits undefined values, preserves the Bearer Authorization header, and uses application/x-www-form-urlencoded; charset=utf-8; focused exact-head test passes (11/11). No source or external-branch mutation was performed.

REQUEST_CHANGES blockers:

  • Fresh exact-head GitHub CI is not green/available: check-runs API reports total_count: 0, commit-status API reports total_count: 0 with state: pending, and gh pr checks reports no checks for the branch.
  • Exact-head package check is not clean: bun --cwd=packages/coding-agent run check fails on the inherited test/agent-session-retry-fallback.test.ts formatting mismatch; the failure is outside this PR diff but means the exact head does not provide clean CI evidence.

Merge gate: no MERGE_READY recommendation and no merge performed. Please provide green checks on this exact head (or an explicitly recorded maintainer-approved CI waiver) and a clean exact-head validation result.

@nahyeongjin1
nahyeongjin1 force-pushed the fix/slack-conversations-replies-form-encoding branch from ba3a16a to 20cbbdc Compare August 3, 2026 13:37
@nahyeongjin1

nahyeongjin1 commented Aug 3, 2026

Copy link
Copy Markdown
Author

Rebased onto current dev and refreshed the exact-head evidence.

  • Exact head: 1c1dd9d64c294be7130f9025497e40864db86046
  • Exact parent/base: dev@ded5926ad3c538a680449d61c1d31ac508499b2e
  • Diff remains exactly 3 files, +44/-2
  • Source/test blobs are byte-identical to the previously reviewed head; the changelog now contains the Slack bullet once and the inherited Telegram bullet once
  • Slack provider+daemon: 60/60 pass, 223 assertions
  • bun --cwd=packages/coding-agent run check: Biome 2,514 files clean; TypeScript pass
  • bun run ci:test:smoke: pass with the published v0.12.11 prebuilt native artifact; no native source build/global install
  • Fresh immutable review: PASS, merge_blocked=false, canonical three-blob digest 5ef617f69e588f0a718da52c178f983a057a3dea6fffd18709c5f99841fca32d

New exact-head fork workflows require maintainer approval:

Maintainer action requested: approve both runs, then refresh the formal review decision for this exact head. No duplicate PR or comment was opened.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Owner resume required; no duplicate mutation opened.

Exact head: 20cbbdc238facfa8d83e3bf387b985976000e56b
Dev CI is red at Affected path validation / plan: PR head does not contain current base dev@f93e49451ef75ddb02e3b3b7e912e133dec525df; rebase onto current dev and let the existing owner continue. No review verdict attached while exact-head CI is red.

@nahyeongjin1
nahyeongjin1 force-pushed the fix/slack-conversations-replies-form-encoding branch 2 times, most recently from 6d36814 to d0dac07 Compare August 3, 2026 13:53
@nahyeongjin1
nahyeongjin1 force-pushed the fix/slack-conversations-replies-form-encoding branch 2 times, most recently from 1c1dd9d to 8c8fcd9 Compare August 4, 2026 13:31
@nahyeongjin1

Copy link
Copy Markdown
Author

Rebased onto current dev (f9dffed426a433bf4948bdeb8fb2fe76f25ef5ca) and force-pushed. New exact head: 8c8fcd98923bb0f1491e4a76c4c9cdb9793f9bdf. The rebase was clean — no conflicts, one commit, diff unchanged at 3 files / +44 −2.

This addresses the second blocker from the 2026-08-03 review directly. That review recorded:

Exact-head package check is not clean: bun --cwd=packages/coding-agent run check fails on the inherited test/agent-session-retry-fallback.test.ts formatting mismatch; the failure is outside this PR diff but means the exact head does not provide clean CI evidence.

That failure was inherited from the old base and has since been fixed upstream. At the new exact head it is gone:

$ bun --cwd=packages/coding-agent run check
$ biome check . && bun run check:types
Checked 2514 files in 1132ms. No fixes applied.
$ tsc -p tsconfig.json --noEmit
# exit 0

$ bun test packages/coding-agent/test/sdk-slack-live-provider.test.ts
 11 pass
 0 fail
 37 expect() calls

Verified in a disposable worktree checked out at exactly 8c8fcd98, not at a local branch that could drift from what was pushed.

On the first blocker — absent GitHub CI evidence — I do not think this is actionable from my side. The workflow runs exist but GitHub is holding them for maintainer approval because this is a fork PR:

$ gh api "repos/Yeachan-Heo/gajae-code/actions/runs?event=pull_request"
Dev CI            completed  action_required
Public site sync  completed  action_required

action_required is why check-runs reports total_count: 0 and why gh pr checks sees nothing. There are 78 runs in this state across the repository. Approving the workflow run on this head would produce the green checks the review asks for; nothing I can push changes that.

Requesting re-review, or a CI approval on 8c8fcd98 if you would rather see the real run before re-reviewing.

Slack's conversations.replies endpoint rejects JSON request bodies with
invalid_arguments even though equivalent form-encoded requests succeed.
Serialize all Slack Web API POST parameters with URLSearchParams, omit
undefined fields, and pin the request contract with a regression test.

Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: Slack provider and daemon 60/60; coding-agent check; CLI smoke

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@nahyeongjin1
nahyeongjin1 force-pushed the fix/slack-conversations-replies-form-encoding branch from 8c8fcd9 to 92ad43d Compare August 4, 2026 17:57
@nahyeongjin1

Copy link
Copy Markdown
Author

Following up on the Affected path validation / plan failure recorded above:

Dev CI is red at Affected path validation / plan: PR head does not contain current base; rebase onto current dev and let the existing owner continue.

dev has moved twice since that comment (f9dffed4, then 732856b3 via #3813). Rebased onto the current tip and force-pushed; new exact head 92ad43dca9b55cdf7f790ff805c76f5f44943379. Conflict-free, one commit, diff unchanged.

The gate is the ancestry check in dev-ci.yml:

if git merge-base --is-ancestor "${GITHUB_BASE_SHA}" HEAD; then :
else echo "::error::Exact-head CI requires this PR head to contain base ${GITHUB_BASE_SHA}; rebase onto current ${GITHUB_BASE_REF}."

Checked locally against the current tip — all three of my open PRs now satisfy it:

#3753 head=92ad43dc  merge-base --is-ancestor 732856b3 -> PASS
#3816 head=0fdceb5e  -> PASS
#3821 head=b57a991f  -> PASS

Exact-head validation at 92ad43dc, in a disposable worktree checked out at that commit:

$ bun --cwd=packages/coding-agent run check
$ biome check . && bun run check:types
Checked 2515 files in 1096ms. No fixes applied.
$ tsc -p tsconfig.json --noEmit
# exit 0

$ bun test packages/coding-agent/test/sdk-slack-live-provider.test.ts
 11 pass
 0 fail

The second blocker from the 2026-08-03 review — the inherited agent-session-retry-fallback.test.ts formatting mismatch — was fixed upstream and no longer reproduces at this head, as noted in my earlier comment.

One practical note: because the gate compares against the base recorded on the triggering event, a head that is current now goes stale whenever dev advances. I would rather not force-push on every dev commit, since each push resets review state for no content change. If the run is approved while the head is current it will pass; if dev moves first, say the word and I will rebase again.

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

OWNER_CONFIRMATION_REQUIRED — exact-head review

Reviewed exact head 92ad43dca9b55cdf7f790ff805c76f5f44943379 against exact base/current dev 732856b3ccb3fade6e9fbc17908a4fbca5a7682f. GitHub reports MERGEABLE / UNSTABLE; the existing formal review decision remains CHANGES_REQUESTED.

Code verdict: MERGE_READY

No functional blocker was found in the form serializer, Bearer authentication, retry behavior, string-only callsites, omission of undefined, or interaction with #3816's added limit: "1" request. The exact-head package check passed, and the focused Slack provider/daemon suites passed 60/60 with 223 assertions.

Why owner confirmation is still required

  • Exact-head Dev CI run 30936309914 and Public site sync run 30936310488 are both action_required because this is a fork workflow.
  • The head has 0 check runs and 0 statuses. This review did not approve or rerun either workflow and does not supply a CI waiver.
  • Current base dev@732856b3 also has a failed Dev CI run (30935832940, shard 8), so the owner must distinguish the base failure from this PR's evidence when admitting or waiving CI.

Owner action is therefore limited to approving exact-head fork workflows or recording an explicit waiver; no source change is required by this verdict.

Non-blocking follow-ups

  • Narrow the comment/changelog claim that Slack categorically rejects JSON: current Slack documentation lists both JSON and form content types for conversations.replies, while the contributor's live deployment evidence supports form encoding as the working contract.
  • Add one literal raw-body assertion covering reserved characters and Unicode; the current ordered URLSearchParams assertions prove the ASCII call contract.

Contributor ledger

#3753 is the canonical contribution from nahyeongjin1. The contributor self-closed #3824 as its duplicate and explicitly preserved #3753's stronger coverage. #3816 is complementary and should consume this prerequisite rather than open another encoding lane.

gajae.pr-review-verdict.v1 OWNER_CONFIRMATION_REQUIRED head:92ad43dca9b55cdf7f790ff805c76f5f44943379 base:732856b3ccb3fade6e9fbc17908a4fbca5a7682f reviewer:Yeachan-Heo code:MERGE_READY

Signed: GJC / Yeachan-Heo via GitHub CLI

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants