Skip to content

Unable to spawn subagents from telegram sessions. #35039

@iceman3k

Description

@iceman3k

Bug type

Regression (worked before, now fails)

Summary

When gateway.auth.mode is set to "token", agent tool calls (e.g., sessions_spawn, cron, sessions_list) fail with a 10-second timeout and "device-required" error. The web UI (Control UI) works fine because it uses a different authentication path that respects dangerouslyDisableDeviceAuth, but the agent tool layer uses a separate code path that doesn't properly resolve gateway credentials from environment variables.

Environment
• OpenClaw version: 2026.3.2
• OS: Ubuntu 24.04.4 LTS (Linux x86_64)
• Gateway auth mode: token
• Environment variables set: OPENCLAW_GATEWAY_TOKEN, OPENCLAW_GATEWAY_PASSWORD
-OR-
• Environment variables set: OPENCLAW_GATEWAY_TOKEN

Steps to reproduce

  1. Configure gateway with auth.mode: "token" and set OPENCLAW_GATEWAY_TOKEN env var
  2. Start gateway: openclaw gateway start
  3. Send a message to an agent via Telegram (or any non-webchat channel)
  4. Have the agent invoke a tool that calls the gateway, e.g.:

sessions_spawn({
runtime: "subagent",
task: "test"
})

Expected behavior

The agent should successfully authenticate to the gateway's tool WebSocket using the OPENCLAW_GATEWAY_TOKEN environment variable (or config), and the tool call should complete and allow spawning of subagents

Actual behavior

Error: gateway timeout after 10000ms
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/openclaw/.openclaw/openclaw.json
Bind: loopback

OpenClaw version

2026.3.2

Operating system

Ubuntu 24.04.4 LTS (Linux x86_64)

Install method

npm global

Logs, screenshots, and evidence

JSON

{
"cause": "device-required",
"handshake": "failed",
"durationMs": 10,
"lastFrameType": "req",
"lastFrameMethod": "connect",
...
}
Root Cause Analysis

The code path for agent tool calls (callGatewayTool):

1. callGatewayTool(method, opts, params) is invoked
2. Calls resolveGatewayOptions$1(opts) to get gateway config
3. resolveGatewayOptions$1 only checks opts?.gatewayToken — no env/config fallback
4. Returns { token: undefined, ... }
5. GatewayClient is created without a token
6. sendConnect() sends auth payload without token
7. Gateway rejects with device-required (because mode: token requires auth)

The code path for CLI/web UI (callGatewayWithScopes):

1. Calls resolveGatewayCredentials(context)
2. Which calls resolveGatewayCredentialsWithEnv(context, process.env)
3. Properly reads OPENCLAW_GATEWAY_TOKEN from env via readGatewayTokenEnv(env)
4. Returns { token: "...", ... }
5. Connection succeeds

Key finding: dangerouslyDisableDeviceAuth only applies to Control UI connections (isControlUi === true), not to agent tool WebSocket connections.

Relevant Code Locations

> Rachael:
Here's the bug report ready to copy-paste:

───

Bug Report: Agent tool calls fail with "device-required" when gateway.auth.mode="token"

Summary

When gateway.auth.mode is set to "token", agent tool calls (e.g., sessions_spawn, cron, sessions_list) fail with a 10-second timeout and "device-required" error. The web UI (Control UI) works fine because it uses a different authentication path that respects dangerouslyDisableDeviceAuth, but the agent tool layer uses a separate code path that doesn't properly resolve gateway credentials from environment variables.

Environment

• OpenClaw version: 2026.3.2
• OS: Ubuntu 24.04.4 LTS (Linux x86_64)
• Gateway auth mode: token
• Environment variables set: OPENCLAW_GATEWAY_TOKEN, OPENCLAW_GATEWAY_PASSWORD

Steps to Reproduce

1. Configure gateway with auth.mode: "token" and set OPENCLAW_GATEWAY_TOKEN env var
2. Start gateway: openclaw gateway start
3. Send a message to an agent via Telegram (or any non-webchat channel)
4. Have the agent invoke a tool that calls the gateway, e.g.:

sessions_spawn({
runtime: "subagent",
task: "test"
})

Expected Behavior

The agent should successfully authenticate to the gateway's tool WebSocket using the OPENCLAW_GATEWAY_TOKEN environment variable (or config), and the tool call should complete.

Actual Behavior

Error: gateway timeout after 10000ms
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Config: /home/openclaw/.openclaw/openclaw.json
Bind: loopback

Gateway logs show:

{
"cause": "device-required",
"handshake": "failed",
"durationMs": 10,
"lastFrameType": "req",
"lastFrameMethod": "connect",
...
}

Root Cause Analysis

The code path for agent tool calls (callGatewayTool):

1. callGatewayTool(method, opts, params) is invoked
2. Calls resolveGatewayOptions$1(opts) to get gateway config
3. resolveGatewayOptions$1 only checks opts?.gatewayToken — no env/config fallback
4. Returns { token: undefined, ... }
5. GatewayClient is created without a token
6. sendConnect() sends auth payload without token
7. Gateway rejects with device-required (because mode: token requires auth)

The code path for CLI/web UI (callGatewayWithScopes):

1. Calls resolveGatewayCredentials(context)
2. Which calls resolveGatewayCredentialsWithEnv(context, process.env)
3. Properly reads OPENCLAW_GATEWAY_TOKEN from env via readGatewayTokenEnv(env)
4. Returns { token: "...", ... }
5. Connection succeeds

Key finding: dangerouslyDisableDeviceAuth only applies to Control UI connections (isControlUi === true), not to agent tool WebSocket connections.

Relevant Code Locations

File: dist/plugin-sdk/reply-DFFRlayb.js (and similar bundled files)

// Bug: resolveGatewayOptions$1 doesn't resolve credentials from env/config
function resolveGatewayOptions$1(opts) {
const cfg = loadConfig();
const explicitToken = trimToUndefined$1(opts?.gatewayToken);
const token = validatedOverride ? resolveGatewayOverrideToken({...}) : explicitToken;
// Missing: fallback to readGatewayTokenEnv(process.env) or resolveGatewayCredentials()
return { url: validatedOverride?.url, token, timeoutMs };
}

// Working: CLI path properly resolves credentials
async function resolveGatewayCredentials(context) {
return resolveGatewayCredentialsWithEnv(context, process.env);
}

async function resolveGatewayCredentialsWithEnv(context, env) {
const envToken = readGatewayTokenEnv(env); // Reads OPENCLAW_GATEWAY_TOKEN
const envPassword = readGatewayPassword

Impact and severity

• Severity: High — breaks core functionality (sub-agents, cron, session management) for non-webchat channels
• Affected tools: sessions_spawn, sessions_list, sessions_history, cron, gateway, nodes, etc.
• Workaround available: Yes (auth mode "none"), but with security trade-off

Additional information

Trying to spawn subagents from telegram sessions

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingregressionBehavior that previously worked and now failsstaleMarked as stale due to inactivity

    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