Skip to content

fix(feishu): avoid axios interceptor internals#89806

Merged
clawsweeper[bot] merged 1 commit into
openclaw:mainfrom
sweetcornna:fix/83913-feishu-ua-interceptor-public-api
Jun 19, 2026
Merged

fix(feishu): avoid axios interceptor internals#89806
clawsweeper[bot] merged 1 commit into
openclaw:mainfrom
sweetcornna:fix/83913-feishu-ua-interceptor-public-api

Conversation

@sweetcornna

@sweetcornna sweetcornna commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Stop clearing Lark.defaultHttpInstance.interceptors.request.handlers at module load.
  • Register the Feishu User-Agent override through the public request.use(...) interceptor API.
  • Cover the import-time regression with a mocked interceptor that throws if private handlers is read or written.

Fixes #83913

Red test

Before the production change, the new extensions/feishu/src/client.test.ts import-time regression failed with:

Error: Do not write axios private interceptor handlers
- extensions/feishu/src/client.ts:75:31

Real behavior proof

  • Behavior or issue addressed: The Feishu client no longer reads or writes the undocumented axios interceptors.request.handlers array during import, and registers its User-Agent override through the public interceptor API.

  • Real environment tested: Local macOS source checkout at PR head b87083193b84f304af0eeebf92c582ed355bdb24, Node via node --import tsx, real bundled @larksuiteoapi/node-sdk default HTTP instance.

  • Exact steps or command run after this patch: Replaced only the public request.use boundary with a counter, made the private handlers property throw on direct read/write, then imported extensions/feishu/src/client.ts through tsx.

  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output): Terminal output from the runtime import probe:

    $ node --import tsx - <<'EOF'
    import * as Lark from "@larksuiteoapi/node-sdk";
    
    const requestInterceptors = Lark.defaultHttpInstance.interceptors.request;
    let publicUseCalls = 0;
    let registeredInterceptorType = "missing";
    requestInterceptors.use = ((fn) => {
      publicUseCalls += 1;
      registeredInterceptorType = typeof fn;
      return publicUseCalls;
    });
    Object.defineProperty(requestInterceptors, "handlers", {
      configurable: true,
      get() {
        throw new Error("proof failed: OpenClaw read private axios handlers");
      },
      set() {
        throw new Error("proof failed: OpenClaw wrote private axios handlers");
      },
    });
    
    const moduleUrl = new URL("./extensions/feishu/src/client.ts?proof=" + Date.now(), import.meta.url);
    const feishuClient = await import(moduleUrl.href);
    console.log(`Feishu UA: ${feishuClient.getFeishuUserAgent()}`);
    console.log(`public request.use calls during import: ${publicUseCalls}`);
    console.log(`registered interceptor type: ${registeredInterceptorType}`);
    console.log("private axios handlers touched by OpenClaw import: no");
    EOF
    Feishu UA: openclaw-feishu-builtin/2026.6.2/darwin
    public request.use calls during import: 1
    registered interceptor type: function
    private axios handlers touched by OpenClaw import: no
    
  • Observed result after fix: Importing the Feishu client succeeded, exactly one public request.use interceptor was registered, the registered callback was a function, and the throwing private handlers accessor was never touched by OpenClaw import code.

  • What was not tested: No live Feishu/Lark network request was sent; this proof verifies the import-time interceptor registration boundary that issue UA interceptor replacement relies on undocumented axios handlers internal #83913 reported.

  • Proof limitations or environment constraints: The probe intentionally avoids credentials and network calls; it uses the real SDK object but instruments the interceptor boundary locally.

  • Before evidence (optional but encouraged): Before the production change, the added regression failed at extensions/feishu/src/client.ts:75:31 with Do not write axios private interceptor handlers.

Validation

  • node scripts/run-vitest.mjs extensions/feishu/src/client.test.ts --reporter=dot -> 18 passed
  • npx oxfmt --check extensions/feishu/src/client.ts extensions/feishu/src/client.test.ts -> passed
  • node scripts/run-oxlint.mjs extensions/feishu/src/client.ts extensions/feishu/src/client.test.ts -> passed
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.extensions.test.json -> passed
  • git diff --check -> passed

@openclaw-barnacle openclaw-barnacle Bot added channel: feishu Channel integration: feishu size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 3, 2026
@clawsweeper

clawsweeper Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Codex review: passed. Reviewed June 19, 2026, 1:49 AM ET / 05:49 UTC.

Summary
The branch replaces Feishu's module-load Axios handlers reset with public request-interceptor registration and adds tests that throw on private handler access.

PR surface: Source +7, Tests +48. Total +55 across 2 files.

Reproducibility: yes. for the source/dependency boundary: current main still writes interceptors.request.handlers = [], and the PR's throwing mock/probe would fail on that access before the production change. No live authenticated Feishu request failure was reproduced.

Review metrics: 1 noteworthy metric.

  • Dependency boundary change: 1 private Axios field write removed; 1 public interceptor API used. The merge decision turns on replacing undocumented dependency storage access with the supported interceptor contract while preserving the SDK stack.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #83913
Summary: This PR is the direct candidate fix for the canonical Feishu Axios-interceptor issue; no separate same-root-cause item was found in targeted GitHub searches.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

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

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

Risk before merge

  • [P1] No authenticated live Feishu/Lark request was sent; review confidence comes from dependency source, regression tests, and terminal import proof of the interceptor boundary rather than an end-to-end API call.

Maintainer options:

  1. Decide the mitigation before merge
    Land this public-interceptor change after exact-head checks and mergeability pass, then let UA interceptor replacement relies on undocumented axios handlers internal #83913 close as implemented by the merge.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] No repair lane is needed; the automerge-opted PR already contains the focused code change, regression coverage, and sufficient terminal proof, so exact-head checks and mergeability can gate landing.

Security
Cleared: The diff changes Feishu client/test code only, adds no dependencies, workflows, permissions, generated code, or secret-handling surface, and reduces reliance on dependency internals.

Review details

Best possible solution:

Land this public-interceptor change after exact-head checks and mergeability pass, then let #83913 close as implemented by the merge.

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

Yes for the source/dependency boundary: current main still writes interceptors.request.handlers = [], and the PR's throwing mock/probe would fail on that access before the production change. No live authenticated Feishu request failure was reproduced.

Is this the best way to solve the issue?

Yes. Registering a public request interceptor that always sets the Feishu User-Agent is the narrow maintainable fix; clearing Axios storage directly or adding a config switch would keep unnecessary dependency-internal coupling.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body includes after-fix terminal proof against the real bundled Lark SDK default HTTP instance showing one public request.use registration and no direct private handlers access.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: 🚀 automerge armed.

Label justifications:

  • P3: This is a narrow Feishu plugin dependency-boundary cleanup with regression coverage and no proven current user-facing outage.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (terminal): The PR body includes after-fix terminal proof against the real bundled Lark SDK default HTTP instance showing one public request.use registration and no direct private handlers access.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix terminal proof against the real bundled Lark SDK default HTTP instance showing one public request.use registration and no direct private handlers access.
Evidence reviewed

PR surface:

Source +7, Tests +48. Total +55 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 32 25 +7
Tests 1 58 10 +48
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 90 35 +55

What I checked:

  • Root repository policy read: The full root AGENTS.md was read and applied, including the requirements for scoped extension policy, dependency contract inspection, best-fix review, and PR proof assessment. (AGENTS.md:1, 2db37c2cd0a5)
  • Scoped extension policy read: The full extensions/AGENTS.md was read and applied; the change stays inside the Feishu plugin boundary and does not add core/plugin API surface. (extensions/AGENTS.md:1, 2db37c2cd0a5)
  • Current main still has the reported private-field access: Current main still casts the Lark default HTTP instance request interceptor to include handlers and assigns inst.interceptors.request.handlers = [] at module load. (extensions/feishu/src/client.ts:76, 2db37c2cd0a5)
  • Latest release still has the same behavior: The latest release tag v2026.6.8 contains the same direct handlers reset, so the linked issue is not already shipped fixed. (extensions/feishu/src/client.ts:76, 844f405ac1be)
  • PR head uses the public interceptor API: At PR head, Feishu registers setRequestUserAgent through inst.interceptors?.request?.use(...) and no longer reads or writes handlers. (extensions/feishu/src/client.ts:90, b87083193b84)
  • Regression tests cover the private-field boundary: The PR test mock defines a throwing handlers accessor and asserts the registered interceptor overrides the SDK User-Agent for plain headers and AxiosHeaders-like headers. (extensions/feishu/src/client.test.ts:38, b87083193b84)

Likely related people:

  • evandance: Authored the merged Feishu User-Agent work whose merge commit added the module-load interceptor block and direct handlers reset now being repaired. (role: introduced behavior; confidence: high; commits: 4fb393980c05; files: extensions/feishu/src/client.ts)
  • niuchong0523: GitHub PR metadata for the Feishu User-Agent change shows this account merged the PR associated with commit 4fb393980c05. (role: merger; confidence: medium; commits: 4fb393980c05; files: extensions/feishu/src/client.ts)
  • vincentkoc: Recent Feishu client history includes nearby timeout/client refactoring and this maintainer also opted the current PR into automerge. (role: recent area contributor; confidence: medium; commits: 282b9fe6168b; files: extensions/feishu/src/client.ts)
  • huntharo: Added the Feishu client runtime injection seam used by the adjacent tests, making this account relevant for the import-time interceptor regression surface. (role: test seam contributor; confidence: medium; commits: 8448f48cc57e; files: extensions/feishu/src/client.ts, extensions/feishu/src/client.test.ts)
  • m1heng: The Feishu package metadata describes the plugin as community maintained by this handle, making them a likely reviewer for Feishu-specific behavior. (role: declared plugin contact; confidence: medium; files: extensions/feishu/package.json)
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: 🐚 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. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jun 3, 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 Jun 3, 2026
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jun 3, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 3, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 3, 2026
@vincentkoc

Copy link
Copy Markdown
Member

/clownfish automerge

@openclaw-clownfish openclaw-clownfish Bot added clownfish:automerge Maintainer opted this Clownfish PR into bounded ClawSweeper-reviewed automerge clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge labels Jun 19, 2026
@openclaw-clownfish

Copy link
Copy Markdown
Contributor

Clownfish is on the reef for this PR. 🐠

I tagged clownfish:automerge and sent ClawSweeper over this exact head. If the sweep finds rough coral, failing checks, or needs-human, I will take another bounded repair lap and ask for a fresh review.

A maintainer can call /clownfish stop any time and I will drift this back to human review.

@clawsweeper clawsweeper Bot added status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 19, 2026
@clawsweeper clawsweeper Bot merged commit 93d0d2a into openclaw:main Jun 19, 2026
269 of 290 checks passed
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

🦞✅
ClawSweeper merged this PR after the passing review.

Source: clawsweeper[bot]
Feedback: structured ClawSweeper verdict: pass (sha=b87083193b84f304af0eeebf92c582ed355bdb24)
Merge status: merged by ClawSweeper automerge
Merged at: 2026-06-19T05:50:54Z
Merge commit: 93d0d2aeddcb

What merged:

  • The branch replaces Feishu's module-load Axios handlers reset with public request-interceptor registration and adds tests that throw on private handler access.
  • PR surface: Source +7, Tests +48. Total +55 across 2 files.
  • Reproducibility: yes. for the source/dependency boundary: current main still writes `interceptors.request.ha ... l on that access before the production change. No live authenticated Feishu request failure was reproduced.

Automerge notes:

  • No ClawSweeper repair was needed after automerge opt-in.

The automerge loop is complete.

Automerge progress:

  • 2026-06-19 05:50:25 UTC review passed b87083193b84 (structured ClawSweeper verdict: pass (sha=b87083193b84f304af0eeebf92c582ed355bd...)
  • 2026-06-19 05:50:57 UTC merged b87083193b84 (merged by ClawSweeper automerge)

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 20, 2026
Summary:
- The branch replaces Feishu's module-load Axios `handlers` reset with public request-interceptor registration and adds tests that throw on private handler access.
- PR surface: Source +7, Tests +48. Total +55 across 2 files.
- Reproducibility: yes. for the source/dependency boundary: current main still writes `interceptors.request.ha ... l on that access before the production change. No live authenticated Feishu request failure was reproduced.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head b870831.
- Required merge gates passed before the squash merge.

Prepared head SHA: b870831
Review: openclaw#89806 (comment)

Co-authored-by: Cornna <96944678+ymylive@users.noreply.github.com>
cxbAsDev pushed a commit to cxbAsDev/openclaw that referenced this pull request Jun 23, 2026
Summary:
- The branch replaces Feishu's module-load Axios `handlers` reset with public request-interceptor registration and adds tests that throw on private handler access.
- PR surface: Source +7, Tests +48. Total +55 across 2 files.
- Reproducibility: yes. for the source/dependency boundary: current main still writes `interceptors.request.ha ... l on that access before the production change. No live authenticated Feishu request failure was reproduced.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head b870831.
- Required merge gates passed before the squash merge.

Prepared head SHA: b870831
Review: openclaw#89806 (comment)

Co-authored-by: Cornna <96944678+ymylive@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge clownfish:automerge Maintainer opted this Clownfish PR into bounded ClawSweeper-reviewed automerge P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UA interceptor replacement relies on undocumented axios handlers internal

2 participants