Summary
Spawning a subagent fails immediately with a Node.js ByteString error if the agent-scoped auth-profiles.json contains a display-truncated (masked) API key string — i.e. a key with a literal U+2026 … character in it.
Reproduction
The file ~/.openclaw/agents/<agent>/agent/auth-profiles.json can end up storing masked key strings like:
{
"openrouter:default": {
"key": "sk-or-…50ec",
"provider": "openrouter",
"type": "api_key"
}
}
When a subagent using that provider is spawned, the masked string is used verbatim as the Bearer token:
Authorization: Bearer sk-or-…50ec
The … (U+2026, decimal 8230) lands at index 13 of the header value. Node.js's WHATWG Headers.append() enforces Latin-1 (ByteString) and throws:
Cannot convert argument to a ByteString because the character at index 13
has a value of 8230 which is greater than 255.
The subagent session ends immediately with stopReason: "error" and no output.
Two separate bugs
Bug 1 — masked key written as real credential
Something in the UI/config path writes back a display-truncated representation of the key (sk-or-…50ec) into auth-profiles.json instead of the real key. This is the root cause.
Bug 2 — missing sanitization on read
normalizeOptionalSecretInput (in normalize-secret-input-qRrabWp3.js) exists precisely to strip non-Latin-1 characters from credentials and prevent ByteString violations. Its own comment says:
Another frequent source of runtime failures is rich-text/Unicode artifacts (smart punctuation, box-drawing chars, etc.) pasted into API keys. These can break HTTP header construction (ByteString violations). Drop non-Latin1 code points so malformed keys fail as auth errors instead of crashing request setup.
However, the code path that reads API keys from agent-scoped auth-profiles.json does not go through this function, so a corrupted key causes a hard crash instead of a graceful auth failure.
Workaround
Delete the offending profile entries from ~/.openclaw/agents/<agent>/agent/auth-profiles.json. The runtime will fall back to the key in openclaw.json.
Tagging
@tyler6204 (agents/subagents)
Environment
- OpenClaw 2026.5.4-beta.1 (c9967eb)
- Node.js v25.9.0
- Linux x64
- Provider: openrouter (openai-completions API)
This issue was created with the help of AI Claude Code.
Summary
Spawning a subagent fails immediately with a Node.js ByteString error if the agent-scoped
auth-profiles.jsoncontains a display-truncated (masked) API key string — i.e. a key with a literal U+2026…character in it.Reproduction
The file
~/.openclaw/agents/<agent>/agent/auth-profiles.jsoncan end up storing masked key strings like:{ "openrouter:default": { "key": "sk-or-…50ec", "provider": "openrouter", "type": "api_key" } }When a subagent using that provider is spawned, the masked string is used verbatim as the Bearer token:
The
…(U+2026, decimal 8230) lands at index 13 of the header value. Node.js's WHATWGHeaders.append()enforces Latin-1 (ByteString) and throws:The subagent session ends immediately with
stopReason: "error"and no output.Two separate bugs
Bug 1 — masked key written as real credential
Something in the UI/config path writes back a display-truncated representation of the key (
sk-or-…50ec) intoauth-profiles.jsoninstead of the real key. This is the root cause.Bug 2 — missing sanitization on read
normalizeOptionalSecretInput(innormalize-secret-input-qRrabWp3.js) exists precisely to strip non-Latin-1 characters from credentials and prevent ByteString violations. Its own comment says:However, the code path that reads API keys from agent-scoped
auth-profiles.jsondoes not go through this function, so a corrupted key causes a hard crash instead of a graceful auth failure.Workaround
Delete the offending profile entries from
~/.openclaw/agents/<agent>/agent/auth-profiles.json. The runtime will fall back to the key inopenclaw.json.Tagging
@tyler6204 (agents/subagents)
Environment
This issue was created with the help of AI Claude Code.