paperclipai/paperclip · error
networkScope="allowlist" requires at least one valid network
Error message
networkScope="allowlist" requires at least one valid networkAllowlist hostname or HTTP(S) networkTrustedUrl.
What it means
Thrown by startNetworkAllowlistProxy when networkScope is "allowlist" but the combined rules from networkAllowlist entries and HTTP(S) networkTrustedUrl entries is empty. An allowlist proxy with zero rules would block every outbound request, which is indistinguishable from "deny" — the library treats that as a misconfiguration and refuses to start the proxy rather than silently degrading into a full deny.
Source
Thrown at packages/adapter-utils/src/local-process-sandbox.ts:241
"Content-Type: application/json; charset=utf-8",
`Content-Length: ${Buffer.byteLength(body)}`,
"",
body,
].join("\r\n");
}
async function startNetworkAllowlistProxy(
allowlist: string[],
trustedUrls: string[],
socketPath: string,
): Promise<NetworkAllowlistProxy> {
assertUnixSocketPathLength(socketPath);
const rules = [
...allowlist.map(parseNetworkAllowlistEntry),
...trustedUrls.map(parseTrustedNetworkUrl).filter((rule): rule is NetworkAllowlistRule => rule !== null),
];
if (rules.length === 0) {
throw new Error(
'networkScope="allowlist" requires at least one valid networkAllowlist hostname or HTTP(S) networkTrustedUrl.',
);
}
const server = http.createServer((request, response) => {
let target: URL;
try {
target = new URL(request.url ?? "");
} catch {
writeProxyError(response, 400, "invalid_request_url", "Paperclip sandbox proxy requires an absolute request URL.");
return;
}
const port = target.port || (target.protocol === "https:" ? "443" : "80");
if (target.protocol !== "http:") {
writeProxyError(response, 400, "https_requires_connect", "HTTPS targets must use CONNECT through the Paperclip sandbox proxy.");
return;
}
if (!isNetworkTargetAllowed(target.hostname, port, rules)) {
writeProxyError(response, 403, "network_target_denied", "Network target denied by Paperclip sandbox policy.");View on GitHub (pinned to 67001ec6eb)
Solutions
- Provide at least one valid entry in networkAllowlist (e.g. ["api.openai.com", "example.com:443"]) or networkTrustedUrls (e.g. ["https://api.openai.com"]).
- If you actually want to block all network egress, switch networkScope to "deny" — that mode does not require any allowlist.
- If using networkTrustedUrls, ensure every URL uses http: or https: — other schemes are silently filtered, which can leave the rule set empty.
- Add a config-layer assertion that rejects { networkScope: "allowlist", networkAllowlist: [], networkTrustedUrls: [] } before sandbox spawn.
Example fix
// before
buildLocalProcessSandboxSpawnTarget({
...input,
options: { ...input.options, networkScope: "allowlist", networkAllowlist: [], networkTrustedUrls: [] },
});
// after
buildLocalProcessSandboxSpawnTarget({
...input,
options: {
...input.options,
networkScope: "allowlist",
networkAllowlist: ["api.openai.com"],
networkTrustedUrls: ["https://api.openai.com"],
},
}); Defensive patterns
Strategy: validation
Validate before calling
function assertAllowlistConfigured(opts: {
networkScope: string | null;
networkAllowlist: unknown[];
networkTrustedUrls: unknown[];
}): void {
if (opts.networkScope !== "allowlist") return;
const valid = [...opts.networkAllowlist, ...opts.networkTrustedUrls].filter((v) => typeof v === "string" && v.length > 0);
if (valid.length === 0) {
throw new Error('networkScope="allowlist" requires non-empty networkAllowlist or networkTrustedUrls');
}
} Try / catch
try {
return await buildLocalProcessSandboxSpawnTarget(input);
} catch (error) {
if (error instanceof Error && error.message.includes('requires at least one valid networkAllowlist')) {
throw new ConfigError("Allowlist mode requires at least one hostname or HTTP(S) trusted URL.", { cause: error });
}
throw error;
} Prevention
- Co-validate { networkScope, networkAllowlist, networkTrustedUrls } at the config boundary.
- If you want full deny, set networkScope="deny"; do not pair "allowlist" with empty rules.
- Reject non-HTTP(S) entries in networkTrustedUrls at the schema level — they are silently dropped and can produce an empty rule set.
When it happens
Trigger: networkScope="allowlist" is set but networkAllowlist and networkTrustedUrls are both omitted, both empty arrays, or contain only entries that fail to parse. parseNetworkAllowlistEntry throws on bad entries upstream of this check, so reaching this message means the arrays produced zero rules without individual parse errors — typically because they were empty or contained only null-returning parseTrustedNetworkUrl inputs (non-HTTP(S) URLs).
Common situations: Config sets networkScope: "allowlist" but forgets to populate networkAllowlist; or networkTrustedUrls contains ftp:// or file:// URLs which parseTrustedNetworkUrl filters out (returns null), leaving zero rules. Also seen when allowlist arrays are typed but never filled because the values live under a different config key.
Related errors
- networkAllowlist[${index}] must be a string.
- networkScope must be "deny" or "allowlist".
- networkAllowlist[${index}] must not be empty.
- networkAllowlist[${index}] must be a hostname, hostname:port
- networkAllowlist[${index}] must use an exact hostname; wildc
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/1e154463a89743d2.
Report an issue: GitHub.