Skip to content

[Bug]: Global fetch interceptor injects Symbol(sensitiveHeaders), breaking discord.js (undici) on Node.js 22 #77846

@VintageAyu

Description

@VintageAyu

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

Yes

Summary

When attempting to use discord.js (v14.x) inside an OpenClaw plugin on Node.js 22, the Discord client immediately crashes during client.login() or any REST API call.

The crash is caused by OpenClaw's global fetch interceptor mutating the init.headers object by injecting a hidden Symbol (Symbol(sensitiveHeaders)). In Node.js 22, the native undici fetch engine strictly validates the Headers initialization object and immediately throws a TypeError if it encounters any non-string Symbol keys.

ERROR LOG:

[plugins] Plugin init error: Headers constructor: Key Symbol(sensitiveHeaders) in init is a symbol, which cannot be converted to a ByteString.

ROOT CAUSE ANALYSIS

  1. discord.js relies on Node's native fetch (undici).

  2. When making an API request, discord.js creates a standard JavaScript object for headers (e.g., { Authorization: "Bot ..." }).

  3. OpenClaw intercepts this fetch call globally and attaches Symbol(sensitiveHeaders) to the headers object (likely for security/tracing).

  4. Node 22's undici engine passes this modified object into new Headers(init).

  5. The Headers constructor iterates over the keys, hits the OpenClaw-injected Symbol, and throws the ByteString conversion error.

CURRENT WORKAROUND

Plugin developers currently have to completely abandon discord.js and write custom polling wrappers using node:https to bypass the OpenClaw fetch interceptor entirely.

SUGGESTED FIXES.

OpenClaw's fetch interceptor should avoid injecting raw Symbols directly into the init.headers dictionary that is passed down to native fetch. If tracing/tracking is required, consider wrapping the fetch promise or attaching the metadata to a different, non-iterable scope that doesn't conflict with undici's strict prototype validation.

MY ENVIRONMENT

-> OS: WSL2 / Ubuntu (Windows)
-> Node.js Version: v22.x
-> OpenClaw Version: Latest (2026.5.x)
-> Plugin Dependencies: discord.js@^14.14.1

Image

Steps to reproduce

  1. Run OpenClaw on Node.js 22.

2.Create a basic OpenClaw plugin and install discord.js@14.14.x.

  1. Attempt to initialize the client:
import { Client, GatewayIntentBits } from "discord.js";

export default definePluginEntry({
  id: "discord_test",
  register(api) {
    const client = new Client({ intents: [GatewayIntentBits.Guilds] });
    // Crashes here during the internal fetch call
    client.login("BOT_TOKEN_HERE").catch(console.error);
  }
});

Expected behavior

When calling client.login() via discord.js inside an OpenClaw plugin, the client should successfully authenticate with the Discord API and establish a WebSocket connection without any internal fetch errors. The global OpenClaw environment should not interfere with standard third-party libraries utilizing native Node.js fetch.

Actual behavior

The OpenClaw gateway's global fetch interceptor taints the init.headers object by injecting a Symbol(sensitiveHeaders). When discord.js's internal undici engine processes this modified headers object on Node.js 22, it immediately crashes with a TypeError complaining about a Symbol that cannot be converted to a ByteString, causing the plugin initialization to fail completely.

OpenClaw version

2026.5.4

Operating system

WSL version: 2.6.3.0(WSL2) Ubuntu

Install method

pnpm dev

Model

google/gemma-31b-it

Provider / routing chain

no

Additional provider/model setup details

No response

Logs, screenshots, and evidence

<img width="1449" height="68" alt="Image" src="https://github.com/user-attachments/assets/25506082-faca-48c4-a9cf-7799c4182da4" />

Impact and severity

Affected : Users who use my plugin
Severity : Critical

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions