Skip to content

fix(agents): sanitize raw HTTP 401 provider errors in user-visible replies (#56197)#77394

Merged
steipete merged 6 commits into
openclaw:mainfrom
jeffrey701:fix/embedded-runner-sanitize-http-401-token-error-56197
May 31, 2026
Merged

fix(agents): sanitize raw HTTP 401 provider errors in user-visible replies (#56197)#77394
steipete merged 6 commits into
openclaw:mainfrom
jeffrey701:fix/embedded-runner-sanitize-http-401-token-error-56197

Conversation

@jeffrey701

@jeffrey701 jeffrey701 commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the embedded-agent user-facing error path for plain provider HTTP 401 credential failures. The reported Feishu/Z.AI case returned HTTP 401: "Invalid token" directly to chat users when an upstream JWT expired mid-session.

This PR keeps token refresh/retry out of scope. It only maps credential-shaped HTTP 401 auth failures to safe re-authentication copy while preserving existing handling for replay-invalid session errors, schema errors, billing/key-limit errors, OpenAI scope errors, and plain 403s.

Fix

  • Adds auth_invalid_token under src/agents/embedded-agent-helpers/errors.ts.
  • Requires both an auth failover classification and positive HTTP 401 evidence.
  • Narrows the matcher to credential-shaped text such as Invalid token, Unauthorized, Incorrect API key, and structured 401 permission payloads whose message is Invalid token.
  • Excludes payloads with known scope hints so provider-less missing-scope observations do not move into the generic invalid-token lane.
  • Removes the direct changelog edit; release generation owns CHANGELOG.md.

Real behavior proof

Behavior addressed: Raw provider credential failures such as HTTP 401: "Invalid token" no longer become chat-visible reply text from formatAssistantErrorText.

Real environment tested: Local OpenClaw source checkout on macOS, using the current embedded-agent helper module directly through the workspace TypeScript runtime after rebasing onto origin/main.

Exact steps or command run after this patch: node_modules/.bin/tsx -e '<direct import of ./src/agents/embedded-agent-helpers/errors.ts and calls to formatAssistantErrorText for raw 401/403/auth payloads>'

Evidence after fix: Direct runtime invocation output from the patched helper:

case 1 raw=HTTP 401: \"Invalid token\"
case 1 formatted=Authentication failed (provider returned HTTP 401). Your provider token may have expired — try the request again in a moment. If the failure persists, re-authenticate this provider.
case 2 raw=HTTP 401: Incorrect API key provided
case 2 formatted=Authentication failed (provider returned HTTP 401). Your provider token may have expired — try the request again in a moment. If the failure persists, re-authenticate this provider.
case 3 raw=401 {\"type\":\"error\",\"error\":{\"type\":\"permission_error\",\"message\":\"Invalid token\"}}
case 3 formatted=Authentication failed (provider returned HTTP 401). Your provider token may have expired — try the request again in a moment. If the failure persists, re-authenticate this provider.
case 4 raw=403 Forbidden
case 4 formatted=HTTP 403: Forbidden
case 5 raw={\"error\":{\"code\":\"invalid_api_key\"}}
case 5 formatted={\"error\":{\"code\":\"invalid_api_key\"}}
case 6 raw=401 {\"type\":\"error\",\"error\":{\"type\":\"permission_error\",\"message\":\"Missing scopes: api.responses.write\"}}
case 6 formatted=401 {\"type\":\"error\",\"error\":{\"type\":\"permission_error\",\"message\":\"Missing scopes: api.responses.write\"}}

Observed result after fix: Credential-shaped 401 cases return the friendly re-authentication copy. Negative controls keep their prior lanes: plain 403 does not claim HTTP 401, message-only auth without HTTP status does not claim HTTP 401, and provider-less missing-scope 401 payloads remain out of the invalid-token lane.

What was not tested: No live Feishu or Z.AI/AutoGLM expired-token session was run. Automatic token refresh/retry remains a separate provider-owned follow-up.

Verification

  • pnpm exec oxfmt --check --threads=1 src/agents/embedded-agent-helpers/errors.ts src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-error-observation.test.ts
  • node scripts/run-vitest.mjs src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-helpers.isbillingerrormessage.test.ts src/agents/embedded-agent-error-observation.test.ts -> 219 helper tests and 16 observation tests passed.
  • .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --parallel-tests "node scripts/run-vitest.mjs src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-helpers.isbillingerrormessage.test.ts src/agents/embedded-agent-error-observation.test.ts" -> clean, no accepted/actionable findings.

Fixes #56197.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels May 4, 2026
@clawsweeper

clawsweeper Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed May 31, 2026, 1:25 AM ET / 05:25 UTC.

Summary
The branch adds provider-runtime classification, formatter copy, and regression tests to replace raw HTTP 401 invalid-token provider errors with a friendly re-authentication hint, plus a CHANGELOG.md entry.

PR surface: Source +62, Tests +102, Docs +1. Total +165 across 3 files.

Reproducibility: yes. from source inspection: current main still lacks a plain HTTP 401 invalid-token formatter branch, so those messages can fall through to raw HTTP/API payload formatting. I did not run the helper in this read-only review.

Review metrics: none identified.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

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

Rank-up moves:

  • Rebase and port the implementation/tests to src/agents/embedded-agent-helpers* on current main.
  • Remove the direct CHANGELOG.md entry and leave release-note context in the PR body.

Risk before merge

  • [P1] Current head is dirty against main, so the intended fix shape is reviewable but the actual merged result is not until the helper rename conflict is resolved.
  • [P1] The linked issue's token refresh/retry behavior remains intentionally out of scope; this PR only fixes the user-visible raw-error copy.

Maintainer options:

  1. Decide the mitigation before merge
    Port the sanitizer and focused tests to the current embedded-agent-helpers files, drop the direct changelog edit, and keep provider token refresh/retry as separate maintainer-owned follow-up work.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] A narrow automated repair can port the accepted fix shape to current helper files and remove the release-owned changelog edit without deciding token-refresh product behavior.

Security
Cleared: The diff changes formatter classification/tests and a changelog entry; I found no dependency, CI, secret, permission, or code-execution surface change.

Review findings

  • [P1] Port the sanitizer to current helper files — src/agents/pi-embedded-helpers/errors.ts:271
  • [P3] Drop the release-owned changelog edit — CHANGELOG.md:1224
Review details

Best possible solution:

Port the sanitizer and focused tests to the current embedded-agent-helpers files, drop the direct changelog edit, and keep provider token refresh/retry as separate maintainer-owned follow-up work.

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

Yes, from source inspection: current main still lacks a plain HTTP 401 invalid-token formatter branch, so those messages can fall through to raw HTTP/API payload formatting. I did not run the helper in this read-only review.

Is this the best way to solve the issue?

Yes for the narrow copy-only scope: sanitizing the embedded-run fallback is the safest interim fix while refresh/retry stays provider-owned. The submitted branch is not the best merge shape until it is ported to the current helper files and the changelog edit is removed.

Full review comments:

  • [P1] Port the sanitizer to current helper files — src/agents/pi-embedded-helpers/errors.ts:271
    Current main moved this surface to src/agents/embedded-agent-helpers/*, and the PR is dirty because it still adds auth_invalid_token to the removed pi-embedded-helpers path. Please rebase and port the implementation plus formatter tests to the current helper files so the actual merged runtime is protected.
    Confidence: 0.96
  • [P3] Drop the release-owned changelog edit — CHANGELOG.md:1224
    Normal PRs should not edit CHANGELOG.md; release-note context belongs in the PR body or squash/direct commit message for release generation. Please remove this changelog entry while keeping the behavior summary in the PR text.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 51dee73a5d3e.

Label changes

Label justifications:

  • P2: This is a normal-priority user-visible auth-provider error handling fix with a narrow repair path, not an urgent runtime outage.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body includes after-fix terminal output from direct runtime helper invocation plus focused regression-suite output for the reported 401 and review controls.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal output from direct runtime helper invocation plus focused regression-suite output for the reported 401 and review controls.
Evidence reviewed

PR surface:

Source +62, Tests +102, Docs +1. Total +165 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 62 0 +62
Tests 1 102 0 +102
Docs 1 1 0 +1
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 165 0 +165

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-helpers.isbillingerrormessage.test.ts.
  • [P1] git diff --check.

What I checked:

Likely related people:

  • Peter Steinberger: Introduced the original formatter split and recently carried the current helper surface into embedded-agent-helpers, so they are a strong routing candidate for the rebase/port shape. (role: recent area contributor; confidence: high; commits: bcbfb357bec7, 0e586bb48a31, 0be3ef5a383d; files: src/agents/pi-embedded-helpers/errors.ts, src/agents/embedded-agent-helpers/errors.ts)
  • Eva: Blame on the PR base shows the provider runtime failure kind union, auth classification path, and formatter classifier call largely came from the auth/runtime-failure classification work. (role: feature-history owner; confidence: high; commits: 8166d592d92f, 0b02b5abd21; files: src/agents/pi-embedded-helpers/errors.ts)
  • stain lu: Auth/HTML provider error classification in the same function traces to this nearby merged fix, which shaped the 401/403 behavior this PR must preserve. (role: adjacent classifier contributor; confidence: medium; commits: e588e904a744; files: src/agents/pi-embedded-helpers/errors.ts)
  • martingarramon: Auth HTML provider response work in the same classifier was merged through their related PR, and they also reviewed this PR's proof and control cases. (role: adjacent reviewer and contributor; confidence: medium; commits: 7f4462e5c06d; files: src/agents/pi-embedded-helpers/errors.ts, src/agents/pi-embedded-helpers.formatassistanterrortext.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.

@martingarramon martingarramon left a comment

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.

The new branch at src/agents/pi-embedded-helpers/errors.ts:976 keys on failoverClassification.reason === "auth", but that reason is set by two upstream paths that are NOT actual HTTP 401 responses:

  1. HTTP 403 fall-through — at errors.ts:666, both status === 401 || status === 403 return the auth reason after billing/permanent-auth precedence. A real 403 (e.g., key revoked, scope-missing) with neither HTML body nor permission_error JSON would classify as auth and display copy claiming HTTP 401 when the provider actually returned 403.

  2. Message-only invalid_api_key — at errors.ts:849, isAuthErrorMessage(raw) returns the same auth reason for messages without any HTTP status prefix. Same false-positive shape: copy claims HTTP 401 when no HTTP status was present.

Concrete fix: since classifyProviderRuntimeFailureKind already receives status (extracted via extractLeadingHttpStatus(raw)?.code in the formatAssistantErrorText caller), gate the new branch on it explicitly:

if (
  failoverClassification?.kind === "reason" &&
  failoverClassification.reason === "auth" &&
  status === 401
) {
  return "auth_invalid_token";
}

This excludes the 403 fall-through (different status) and the message-only path (status is undefined). For those cases the existing fallback copy applies — which is what users saw before this change for those shapes, so no behavior regression.

Test gap: the PR's existing negative test covers 401 billing / permanent-auth, but not:

  • Plain 403 falling to generic auth (e.g. "403 Forbidden" without permission_error JSON or HTML body)
  • Message-only invalid_api_key (e.g. '{"error":{"code":"invalid_api_key"}}' with no HTTP status prefix)

Both should assert the output does NOT contain "HTTP 401". Adding these alongside the existing positive tests will prevent accidental re-broadening of the gate.

The PR's direction is correct; the user-visible regression is real. The gate-on-status fix above is the narrowest path to ship this without expanding scope into the token-refresh question.

@jeffrey701

Copy link
Copy Markdown
Contributor Author

martingarramon

I updated this, can you check it?

@martingarramon martingarramon left a comment

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.

LGTM. The new gate requires explicit 401 evidence, so the plain 403 fall-through and message-only invalid_api_key cases no longer produce the HTTP 401 invalid-token copy. The added negative tests cover both regressions from the review, and the ambiguous message-text path avoids over-claiming a specific HTTP status. Passing this back to maintainers.

@martingarramon martingarramon left a comment

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.

Both concerns from the earlier round are addressed.

The 401-evidence gate (status === 401 || (status === undefined && messageMentions401 && !messageMentions403)) correctly excludes plain-403 fall-throughs and message-only payloads — the two shapes I flagged. Conservative in the right direction: a rare message embedding both 401 and 403 falls through to the generic auth path rather than claiming auth_invalid_token. The two negative tests pin this directly; the 'status code: 401, message: "expired token"' variant exercises the status === undefined leg of the gate.

LGTM.

@jeffrey701 jeffrey701 force-pushed the fix/embedded-runner-sanitize-http-401-token-error-56197 branch from da2b17a to 08dcfcb Compare May 10, 2026 14:11
jeffrey701 added a commit to jeffrey701/openclaw that referenced this pull request May 10, 2026
@jeffrey701

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (now at c3a05f652b) to clear the CHANGELOG drift. The conflict was purely additive in the Unreleased > Fixes section — kept both my auth_invalid_token bullet and the new upstream entries.

No code changes since @martingarramon's LGTM: same two commits (2590d63 + 08dcfcb), same diff stat (3 files, +165/-0), same identity. The 401-evidence gate at errors.ts:962 is byte-for-byte unchanged.

Card should be back to green and mergeable now.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 10, 2026

@martingarramon martingarramon left a comment

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.

LGTM holds after the May 10 rebase. The fix shape is unchanged (2590d63 + 08dcfcbc), the 403 anti-regression test is in, and the billing/auth_permanent precedence gate is pinned.

Remaining CI: Real behavior proof failure still needs your rerun/proof submission. checks-fast-contracts-plugins failure looks rerun/rebase-sensitive given the main-churn failure shape at the time of that push — current main is clean.

@jeffrey701 jeffrey701 force-pushed the fix/embedded-runner-sanitize-http-401-token-error-56197 branch from 08dcfcb to 1a5dffd Compare May 14, 2026 16:06
jeffrey701 added a commit to jeffrey701/openclaw that referenced this pull request May 14, 2026
@jeffrey701

Copy link
Copy Markdown
Contributor Author

Rebased onto current upstream/main (83d7ab0d36) — new head 1a5dffdd59. The two commits (45f46749a4 + 1a5dffdd59 ≡ your 2590d63 + 08dcfcbc in shape) replay clean against the post-#81357 main, which should clear the checks-fast-contracts-plugins(-c) flakes you flagged.

For RBP I dropped a 5-case direct-invocation capture of formatAssistantErrorText into the PR body — covers the #56197 raw 401, the two #77394 review controls (plain 403 + message-only auth must not claim 401), and the auth_permanent billing precedence — plus the matching 5 vitest cases. 68/68 in the file still green.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 14, 2026
@martingarramon

Copy link
Copy Markdown
Contributor

RBP block added. The five cases cover the review control points: raw 401 evidence, plain 403 fall-through without a 401 claim, message-only path, billing precedence, and the undefined-status/401-mention leg.

LGTM still holds.

@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 15, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 15, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 15, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 15, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 15, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 15, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 16, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 31, 2026
@clawsweeper clawsweeper Bot added the rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. label May 31, 2026
@barnacle-openclaw barnacle-openclaw Bot removed the stale Marked as stale due to inactivity label May 31, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels May 31, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 31, 2026
@steipete steipete self-assigned this May 31, 2026
@steipete steipete force-pushed the fix/embedded-runner-sanitize-http-401-token-error-56197 branch from 1a5dffd to 81b255e Compare May 31, 2026 18:21
@openclaw-barnacle openclaw-barnacle Bot added triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. proof: supplied External PR includes structured after-fix real behavior proof. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 31, 2026
@steipete

Copy link
Copy Markdown
Contributor

Land-ready after maintainer fixup.

What changed since the original branch:

  • Ported the sanitizer from the stale pi-embedded-helpers path to current src/agents/embedded-agent-helpers/*.
  • Removed the direct CHANGELOG.md edit.
  • Kept the 401-evidence gate, then narrowed it to credential-shaped 401 auth failures so scope, billing, replay, schema, and 403 paths keep their existing behavior.
  • Added coverage for provider-less missing-scope payloads, structured permission_error / Invalid token, and Incorrect API key provided.

Local proof on head 81b255e6b18e510b2c4e70eea99855b7a465b883:

  • pnpm exec oxfmt --check --threads=1 src/agents/embedded-agent-helpers/errors.ts src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-error-observation.test.ts
  • node scripts/run-vitest.mjs src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-helpers.isbillingerrormessage.test.ts src/agents/embedded-agent-error-observation.test.ts -> 219 helper tests and 16 observation tests passed.
  • .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --parallel-tests "node scripts/run-vitest.mjs src/agents/embedded-agent-helpers.formatassistanterrortext.test.ts src/agents/embedded-agent-helpers.isbillingerrormessage.test.ts src/agents/embedded-agent-error-observation.test.ts" -> clean, no accepted/actionable findings.

GitHub proof:

Known gap: no live Feishu or Z.AI/AutoGLM expired-token session was run; token refresh/retry remains separate provider-owned follow-up work.

@steipete steipete merged commit 01ef169 into openclaw:main May 31, 2026
184 of 194 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: S status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Feishu embedded agent returns HTTP 401 "Invalid token" to user instead of retrying with refreshed token

3 participants