What happened?
On this machine web_fetch fails for every hostname:
ToolCallError: URL hostname "support.optimizely.com" resolves to a non-public IP address
web_search still works, so only the local fetch provider is affected. The cause is the SSRF pre-check in the bundled @deepseek-ai/dsh-web-fetch-http@0.1.5-rc.1: the system resolver returns an address from the local proxy's fake-IP pool (198.18.0.0/15), the guard classifies it as non-public, and the whole answer set is rejected with WEB_BLOCKED_URL.
Root cause is upstream and already reported there (discussion #5202, duplicates #6112 / #6457 / #6737). Filing it here because the failure ships inside PawWork, and the copy that actually runs is the one in the app bundle.
Which area seems affected?
Model harness, prompts, tools, or session mechanics
How much does this affect you?
Breaks an important workflow (there is a workaround)
Steps to reproduce
- Run on macOS behind a TUN/fake-IP proxy. Here: Clash Verge Rev, TUN mode,
fake-ip-range: 198.18.0.1/16, mixed-port: 7897.
- Confirm the resolver:
dig www.barra.ai → 198.18.1.51; github.com → 198.18.0.31; even www.baidu.com → 198.18.1.54 (in this setup every host lands in the fake-IP pool).
- Ask PawWork to fetch any https URL, e.g.
https://support.optimizely.com/hc/en-us/articles/4410284003341-Statistical-significance.
ToolCallError: URL hostname "…" resolves to a non-public IP address.
curl to the same URLs returns 200, both direct and through http://127.0.0.1:7897. The network path is fine; only the guard rejects.
What did you expect to happen?
web_fetch returns the page. This machine already has the system HTTP/HTTPS proxy configured (scutil --proxy reports HTTP, HTTPS and SOCKS all at 127.0.0.1:7897), so the fetch should be able to use it without manual environment setup.
PawWork version
2026.9.8
OS version
macOS 27.0 (26A428), arm64
Can you reproduce it again?
Yes, every time
Diagnostics
- Bundled package:
Contents/Resources/app/node_modules/@deepseek-ai/dsh-web-fetch-http 0.1.5-rc.1. <DSH_HOME>/profiles/node_modules/@deepseek-ai/dsh-web-fetch-http is a symlink into the app bundle, so a PawWork patch is what reaches the runtime.
- Throwing line:
lib/index.js:70 — if (!isPublicIpAddress(entry.address)) throw new WebError(...). isPublicIpAddress is ipaddr.js range() === "unicast", and 198.18.1.47 classifies as reserved.
- Upgrade does not fix it:
0.1.5-rc.2 and 0.1.6-alpha.1 are the newest published versions and their lib/index.js files are byte-identical to each other (diff → 0 lines), with the same check.
- The proxy escape hatch is not automatic:
proxyRouteFor reads http_proxy / https_proxy / no_proxy from the environment only, and macOS system proxy settings are not read. With no HTTPS_PROXY set, the fetch takes the direct path, resolves through the fake-IP resolver, and throws. Upstream comments confirm a proxied hop skips resolution and pinning by design (provider.ts:123-125, asserted by tests/proxy.spec.ts:75-86).
Suggested fix (PawWork side, follows the existing patch pattern)
pnpm-workspace.yaml already patches two DSH packages (dsh-client-connection, dsh-llm-pi-ai). Add a third for dsh-web-fetch-http@0.1.5-rc.1:
- When
HTTPS_PROXY/HTTP_PROXY are absent, fall back to the platform proxy (macOS scutil --proxy), which makes the documented escape hatch the default instead of something the user has to discover.
- Treat the known fake-IP ranges (
198.18.0.0/15) as "local DNS is owned by a proxy" and route that hop through the proxy, instead of pinning an address that cannot be connected to.
SSRF posture is unchanged: RFC1918/loopback/cloud-metadata answers and IP literals stay rejected.
Workaround until then
Set both HTTP_PROXY and HTTPS_PROXY to the local mixed port (http://127.0.0.1:7897) in the environment the DSH sidecar starts with. HTTPS_PROXY alone is not enough — the fallback is asymmetric, so plain http:// URLs still fail (upstream comment, 2026-09-15).
Not urgent: there is a workaround, and the upstream discussion is already tracking the root cause.
What happened?
On this machine
web_fetchfails for every hostname:web_searchstill works, so only the local fetch provider is affected. The cause is the SSRF pre-check in the bundled@deepseek-ai/dsh-web-fetch-http@0.1.5-rc.1: the system resolver returns an address from the local proxy's fake-IP pool (198.18.0.0/15), the guard classifies it as non-public, and the whole answer set is rejected withWEB_BLOCKED_URL.Root cause is upstream and already reported there (discussion #5202, duplicates #6112 / #6457 / #6737). Filing it here because the failure ships inside PawWork, and the copy that actually runs is the one in the app bundle.
Which area seems affected?
Model harness, prompts, tools, or session mechanics
How much does this affect you?
Breaks an important workflow (there is a workaround)
Steps to reproduce
fake-ip-range: 198.18.0.1/16,mixed-port: 7897.dig www.barra.ai→198.18.1.51;github.com→198.18.0.31; evenwww.baidu.com→198.18.1.54(in this setup every host lands in the fake-IP pool).https://support.optimizely.com/hc/en-us/articles/4410284003341-Statistical-significance.ToolCallError: URL hostname "…" resolves to a non-public IP address.curlto the same URLs returns 200, both direct and throughhttp://127.0.0.1:7897. The network path is fine; only the guard rejects.What did you expect to happen?
web_fetchreturns the page. This machine already has the system HTTP/HTTPS proxy configured (scutil --proxyreports HTTP, HTTPS and SOCKS all at127.0.0.1:7897), so the fetch should be able to use it without manual environment setup.PawWork version
2026.9.8
OS version
macOS 27.0 (26A428), arm64
Can you reproduce it again?
Yes, every time
Diagnostics
Contents/Resources/app/node_modules/@deepseek-ai/dsh-web-fetch-http0.1.5-rc.1.<DSH_HOME>/profiles/node_modules/@deepseek-ai/dsh-web-fetch-httpis a symlink into the app bundle, so a PawWork patch is what reaches the runtime.lib/index.js:70—if (!isPublicIpAddress(entry.address)) throw new WebError(...).isPublicIpAddressisipaddr.jsrange() === "unicast", and198.18.1.47classifies asreserved.0.1.5-rc.2and0.1.6-alpha.1are the newest published versions and theirlib/index.jsfiles are byte-identical to each other (diff→ 0 lines), with the same check.proxyRouteForreadshttp_proxy/https_proxy/no_proxyfrom the environment only, and macOS system proxy settings are not read. With noHTTPS_PROXYset, the fetch takes the direct path, resolves through the fake-IP resolver, and throws. Upstream comments confirm a proxied hop skips resolution and pinning by design (provider.ts:123-125, asserted bytests/proxy.spec.ts:75-86).Suggested fix (PawWork side, follows the existing patch pattern)
pnpm-workspace.yamlalready patches two DSH packages (dsh-client-connection,dsh-llm-pi-ai). Add a third fordsh-web-fetch-http@0.1.5-rc.1:HTTPS_PROXY/HTTP_PROXYare absent, fall back to the platform proxy (macOSscutil --proxy), which makes the documented escape hatch the default instead of something the user has to discover.198.18.0.0/15) as "local DNS is owned by a proxy" and route that hop through the proxy, instead of pinning an address that cannot be connected to.SSRF posture is unchanged: RFC1918/loopback/cloud-metadata answers and IP literals stay rejected.
Workaround until then
Set both
HTTP_PROXYandHTTPS_PROXYto the local mixed port (http://127.0.0.1:7897) in the environment the DSH sidecar starts with.HTTPS_PROXYalone is not enough — the fallback is asymmetric, so plainhttp://URLs still fail (upstream comment, 2026-09-15).Not urgent: there is a workaround, and the upstream discussion is already tracking the root cause.