openclaw - ✅(Solved) Fix [Bug]: Gateway never binds when tools.web.fetch key is present in config [2 pull requests, 3 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74896Fetched 2026-05-01 05:40:14
View on GitHub
Comments
3
Participants
3
Timeline
10
Reactions
2
Author
Timeline (top)
commented ×3cross-referenced ×2labeled ×2referenced ×2

OpenClaw 2026.4.26 gateway starts but never binds its gateway port when tools.web.fetch is present in openclaw.json.

Root Cause

Affected: OpenClaw gateway users with tools.web.fetch present in config on 2026.4.26. Severity: High, because the gateway remains alive but unreachable. Frequency: Reproduced consistently during isolation. Consequence: Gateway never binds the local port, so health checks and local clients cannot connect.

Fix Action

Fixed

PR fix notes

PR #74921: fix(secrets): skip web tool discovery when surface is explicitly disabled (#74896)

Description (problem / solution / changelog)

Summary

  • Symptom: OpenClaw 2026.4.26 gateway starts but never binds its port when tools.web.fetch is present in openclaw.json. With OPENCLAW_GATEWAY_STARTUP_TRACE=1, the trace stops after config.snapshot and never reaches config.auth. Setting tools.web.fetch.enabled=false does not fix it; only removing the tools.web.fetch key entirely lets startup proceed. Reported as a regression on 2026.4.26 in #74896.
  • Why it matters: the gateway looks alive but is unreachable. Health checks and local clients can't connect, and the user's "Expected behavior" explicitly asks for enabled=false to be a real escape hatch: "If tools.web.fetch.enabled=false, fetch provider discovery should not block gateway startup."
  • What changed: resolveRuntimeWebTools (src/secrets/runtime-web-tools.ts) now short-circuits the search and fetch discovery branches when the tool surface is explicitly enabled: false, has no plugin-scoped config (plugins.entries.<id>.config.web{Search,Fetch}), and carries no nested object fields (no credential subkeys like firecrawl: { apiKey: ... }). The empty-config fast-path early return that already existed for the no-key case is now mirrored at the per-surface granularity.
  • What did NOT change: disabled tools that DO carry credential subkeys still run discovery so inactive-surface SecretRef warnings remain accurate (the existing test "keeps configured provider metadata and inactive warnings when search is disabled" still passes). The full root-cause investigation of why bundled manifest discovery stalls on Linux/Docker on this code path is left as a separate concern; this PR delivers the user's explicit enabled: false workaround.

Change Type

  • Bug fix

Scope

  • API / contracts (config behavior)
  • Gateway / orchestration (startup path)

Linked Issue/PR

  • Closes #74896
  • This PR fixes a bug or regression

Root Cause

resolveRuntimeWebTools reached resolveRuntimeWebProviderSurface → bundled-plugin manifest scan whenever a tool surface had any object in config, regardless of enabled. On affected Linux/Docker environments, that manifest scan during startup secrets activation does not return promptly, so prepareGatewayStartupConfig never resolves and the gateway never reaches the HTTP bind step.

Code flow that hangs (current main):

  • prepareSecretsRuntimeSnapshotresolveRuntimeWebTools (src/secrets/runtime.ts:362)
  • resolveRuntimeWebTools enters the if (fetch || hasPluginWebFetchConfig) branch even when fetch.enabled === false (src/secrets/runtime-web-tools.ts:682)
  • That branch awaits resolveRuntimeWebProviderSurfaceresolveBundledWebFetchProviders → bundled manifest registry load.

This regressed in 74059aaa29 fix(secrets): honor plugin install ledger for web fetch discovery (Apr 25), which threaded await getHasCustomWebFetchRisk() into the fetch resolveProviders callback and added a load to loadRuntimeWebToolsManifest().

Regression Test Plan

3 new tests in src/secrets/runtime-web-tools.test.ts:

  • disabled credential-free fetch skips fetch discovery — mirrors the user's exact reproducer config (tools.web.fetch: { enabled: false, maxChars, maxCharsCap }, empty plugins.entries); asserts none of the bundled-public-artifacts mocks or the plugin fallback mock are called.
  • disabled credential-free search skips search discovery — same shape on the search side.
  • disabled fetch with nested credential block still runs discovery — guards against regressing the "inactive surface SecretRef warning" contract: when fetch.firecrawl.apiKey is a SecretRef, discovery still happens even with enabled: false.

Test Plan

  • pnpm test src/secrets/runtime-web-tools.test.ts — 36/36 pass (33 existing + 3 new)
  • pnpm tsgo:core — clean
  • pnpm tsgo:core:test — clean
  • pnpm exec oxfmt --write --threads=1 … — clean

Notes

  • Honest scope acknowledgment: I do not have a Linux/Docker repro of the deeper hang, so the underlying manifest-scan stall is not addressed here. This PR ships the user's explicit enabled: false escape hatch and tightens the fast-path to match the no-key case. Full root-cause investigation of the manifest-scan stall (likely in loadRuntimeWebToolsManifest() → bundled plugin discovery on slow filesystems) should land in a follow-up after a maintainer with the affected environment can profile the stall.
  • The optimization also incidentally helps users who simply do not need the web fetch tool but want to keep the config key present for documentation/policy reasons.

Changed files

  • src/secrets/runtime-web-tools.test.ts (modified, +154/-0)
  • src/secrets/runtime-web-tools.ts (modified, +47/-2)

PR #74924: fix(secrets): skip web-fetch provider discovery when tools.web.fetch is explicitly disabled

Description (problem / solution / changelog)

Problem

When tools.web.fetch is present in openclaw.json with enabled: false, the gateway startup hangs indefinitely before binding its port. Removing the fetch key from config restores normal startup.

Fixes #74896

Root cause

hasRuntimeWebToolConfigSurface returns true for any tools.web.fetch object — including { enabled: false }. This bypasses the secrets fast path and triggers resolveRuntimeWebProviderSurface, which unconditionally awaits resolveProviders() (bundled/plugin web-fetch discovery) regardless of the enabled flag. On network-constrained or Docker environments, provider discovery can stall indefinitely.

Fix

Two-layer guard:

src/secrets/runtime.tshasRuntimeWebToolConfigSurface now excludes tools.web.fetch from the slow-path gate when fetch.enabled === false. Disabled-fetch configs use the fast path and skip all provider discovery.

src/secrets/runtime-web-tools.tsresolveRuntimeWebTools guards the fetch surface resolution block with fetchExplicitlyDisabled, so provider discovery is also skipped at the resolver level for belt-and-suspenders safety (protects callers that invoke resolveRuntimeWebTools directly).

Tests

pnpm test src/secrets/runtime-web-tools.test.ts src/secrets/runtime.fast-path.test.ts src/gateway/server-startup-config.secrets.test.ts

45/45 pass. New regression tests:

  • runtime.fast-path.test.ts: "uses the fast path when tools.web.fetch is present but explicitly disabled"
  • runtime-web-tools.test.ts: "skips fetch provider discovery when tools.web.fetch.enabled is false"

Changed files

  • src/secrets/runtime-web-tools.test.ts (modified, +54/-20)
  • src/secrets/runtime-web-tools.ts (modified, +5/-1)
  • src/secrets/runtime.fast-path.test.ts (modified, +20/-0)
  • src/secrets/runtime.ts (modified, +11/-2)

Code Example

OPENCLAW_GATEWAY_STARTUP_TRACE=1 \
   OPENCLAW_GATEWAY_PORT=18789 \
   openclaw gateway --port 18789 --verbose

### Expected behavior

The gateway should bind `127.0.0.1:18789` and expose its health endpoint when `tools.web.fetch` is present in config. If `tools.web.fetch.enabled=false`, fetch provider discovery should not block gateway startup.

### Actual behavior

The gateway process stays alive but never opens `127.0.0.1:18789`. With `OPENCLAW_GATEWAY_STARTUP_TRACE=1`, the trace stops after `config.snapshot` and never reaches `config.auth`, `starting HTTP server`, `http.bound`, or `http server listening`.

Setting `tools.web.fetch.enabled=false` does not fix it. Removing the `tools.web.fetch` key entirely allows the gateway to start and bind normally.

### OpenClaw version

2026.4.26

### Operating system

Linux

### Install method

Docker / Kubernetes container (openclaw-operator https://github.com/openclaw-rocks/openclaw-operator)

### Model

openai-codex/gpt-5.5

### Provider / routing chain

openai-codex/gpt-5.5

### Additional provider/model setup details

The issue reproduces even after removing explicit plugin entries, clearing plugin allowlist, disabling Discord/Telegram channel auto-enable surfaces, and removing model/imageModel/cliBackends defaults. The remaining minimal triggering condition observed was `tools.web.fetch` present in config with plugins enabled.

### Logs, screenshots, and evidence

---

### Impact and severity

Affected: OpenClaw gateway users with `tools.web.fetch` present in config on 2026.4.26.
Severity: High, because the gateway remains alive but unreachable.
Frequency: Reproduced consistently during isolation.
Consequence: Gateway never binds the local port, so health checks and local clients cannot connect.

### Additional information

This appears to be a regression.

Last known good version: `2026.4.24`  
First known bad version observed: `2026.4.26`

Rollback to `2026.4.24` resolves the issue.

Suspected area from source inspection:
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

OpenClaw 2026.4.26 gateway starts but never binds its gateway port when tools.web.fetch is present in openclaw.json.

Steps to reproduce

  1. Start OpenClaw 2026.4.26 with gateway.mode=local, gateway.bind=loopback, and tools.web.fetch present in openclaw.json.

  2. Run the gateway with startup tracing:

    OPENCLAW_GATEWAY_STARTUP_TRACE=1 \
    OPENCLAW_GATEWAY_PORT=18789 \
    openclaw gateway --port 18789 --verbose

Expected behavior

The gateway should bind 127.0.0.1:18789 and expose its health endpoint when tools.web.fetch is present in config. If tools.web.fetch.enabled=false, fetch provider discovery should not block gateway startup.

Actual behavior

The gateway process stays alive but never opens 127.0.0.1:18789. With OPENCLAW_GATEWAY_STARTUP_TRACE=1, the trace stops after config.snapshot and never reaches config.auth, starting HTTP server, http.bound, or http server listening.

Setting tools.web.fetch.enabled=false does not fix it. Removing the tools.web.fetch key entirely allows the gateway to start and bind normally.

OpenClaw version

2026.4.26

Operating system

Linux

Install method

Docker / Kubernetes container (openclaw-operator https://github.com/openclaw-rocks/openclaw-operator)

Model

openai-codex/gpt-5.5

Provider / routing chain

openai-codex/gpt-5.5

Additional provider/model setup details

The issue reproduces even after removing explicit plugin entries, clearing plugin allowlist, disabling Discord/Telegram channel auto-enable surfaces, and removing model/imageModel/cliBackends defaults. The remaining minimal triggering condition observed was tools.web.fetch present in config with plugins enabled.

Logs, screenshots, and evidence

Config shape that reproduces the hang:


{
  "tools": {
    "web": {
      "fetch": {
        "enabled": true,
        "maxChars": 200000,
        "maxCharsCap": 2000000
      }
    }
  },
  "plugins": {
    "enabled": true,
    "allow": [],
    "entries": {},
    "slots": {}
  }
}


Startup trace with `tools.web.fetch` present stops after `config.snapshot`:


[gateway] startup trace: config.snapshot ...


The gateway never reaches:


[gateway] startup trace: config.auth ...
[gateway] starting HTTP server...
[gateway] startup trace: http.bound ...
[gateway] http server listening


Setting fetch disabled still hangs:


{
  "tools": {
    "web": {
      "fetch": {
        "enabled": false,
        "maxChars": 200000,
        "maxCharsCap": 2000000
      }
    }
  }
}


Removing the `fetch` key entirely allows startup to proceed:


[gateway] startup trace: config.auth 2.3ms
[gateway] startup trace: control-ui.seed 0.1ms
[gateway] startup trace: plugins.bootstrap 317.4ms
[gateway] startup trace: runtime.config 1.5ms
[gateway] starting HTTP server...
[gateway] startup trace: http.bound 163.3ms
[gateway] http server listening


Additional isolation performed:

- Removed explicit plugin entries.
- Cleared plugin allowlist.
- Disabled Discord and Telegram channel auto-enable surfaces.
- Removed model/imageModel/cliBackends defaults.
- Confirmed `/home/openclaw/.openclaw/plugins/installs.json` was missing, so persisted installed plugin records were not the trigger.

The issue still reproduced with `tools.web.fetch` present, and stopped reproducing when the `tools.web.fetch` key was removed.

Impact and severity

Affected: OpenClaw gateway users with tools.web.fetch present in config on 2026.4.26. Severity: High, because the gateway remains alive but unreachable. Frequency: Reproduced consistently during isolation. Consequence: Gateway never binds the local port, so health checks and local clients cannot connect.

Additional information

This appears to be a regression.

Last known good version: 2026.4.24
First known bad version observed: 2026.4.26

Rollback to 2026.4.24 resolves the issue.

Suspected area from source inspection:

prepareSecretsRuntimeSnapshot()
  -> hasRuntimeWebToolConfigSurface()
  -> resolveRuntimeWebTools()
  -> fetch provider discovery / resolveRuntimeWebProviderSurface()

extent analysis

TL;DR

The issue can likely be fixed by removing or reconfiguring the tools.web.fetch key in the openclaw.json configuration file.

Guidance

  • Verify that the tools.web.fetch key is the root cause by removing it and checking if the gateway starts and binds correctly.
  • Try setting tools.web.fetch.enabled to false and see if it makes a difference, although the issue report suggests this may not work.
  • Check the OpenClaw documentation for any specific requirements or constraints related to the tools.web.fetch configuration.
  • Consider rolling back to version 2026.4.24, which is reported to work correctly.

Example

No code snippet is provided as the issue seems to be related to configuration rather than code.

Notes

The issue appears to be a regression introduced in version 2026.4.26, and rolling back to 2026.4.24 resolves the issue. However, this may not be a viable long-term solution, and further investigation into the tools.web.fetch configuration and its interaction with the gateway startup process may be necessary.

Recommendation

Apply a workaround by removing or reconfiguring the tools.web.fetch key, as this is the most direct way to resolve the issue based on the provided information.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The gateway should bind 127.0.0.1:18789 and expose its health endpoint when tools.web.fetch is present in config. If tools.web.fetch.enabled=false, fetch provider discovery should not block gateway startup.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING