paperclipai/paperclip · error
networkScope must be "deny" or "allowlist".
Error message
networkScope must be "deny" or "allowlist".
What it means
Thrown by parseLocalProcessNetworkScope when the supplied value is not null, not empty, and not exactly the strings "deny" or "allowlist". The scope controls whether the sandbox blocks all network egress ("deny") or routes traffic through an allowlist proxy ("allowlist"). Only two modes are implemented; passing any other literal is treated as programmer error rather than defaulted.
Source
Thrown at packages/adapter-utils/src/local-process-sandbox.ts:154
if (!hostname || hostname === "*" || hostname.startsWith("*.")) {
throw new Error(`networkAllowlist[${index}] must use an exact hostname; wildcards are not supported.`);
}
return { hostname, port };
}
export function parseLocalProcessNetworkAllowlist(value: unknown): string[] {
if (!Array.isArray(value)) return [];
return value.map((entry, index) => {
if (typeof entry !== "string") throw new Error(`networkAllowlist[${index}] must be a string.`);
const rule = parseNetworkAllowlistEntry(entry, index);
return rule.port ? `${rule.hostname}:${rule.port}` : rule.hostname;
});
}
export function parseLocalProcessNetworkScope(value: unknown): LocalProcessNetworkScope | null {
if (value == null || value === "") return null;
if (value === "deny" || value === "allowlist") return value;
throw new Error('networkScope must be "deny" or "allowlist".');
}
export function parseLocalProcessFilesystemScope(value: unknown): "workspace" | null {
if (value == null || value === "") return null;
if (value === "workspace") return value;
throw new Error('filesystemScope must be "workspace".');
}
function isNetworkTargetAllowed(hostname: string, port: string, rules: NetworkAllowlistRule[]): boolean {
const normalizedHostname = hostname.toLowerCase().replace(/^\[|\]$/g, "");
return rules.some((rule) => rule.hostname === normalizedHostname && (rule.port === null || rule.port === port));
}
function assertUnixSocketPathLength(socketPath: string): void {
const pathBytes = Buffer.byteLength(socketPath);
if (pathBytes > UNIX_SOCKET_PATH_MAX_BYTES) {
throw new Error(
`Paperclip sandbox proxy socket path is ${pathBytes} bytes, exceeding the Linux limit of ${UNIX_SOCKET_PATH_MAX_BYTES}: ${socketPath}`,View on GitHub (pinned to 67001ec6eb)
Solutions
- Use exactly one of the two accepted literals: "deny" or "allowlist".
- Map legacy or UI values to the canonical vocabulary before parsing: { whitelist: "allowlist", off: "deny", on: "allowlist" }.
- To disable sandbox networking entirely, pass null, undefined, or "" — these return null and the scope is treated as unset.
- Add a unit test that round-trips every accepted spelling through parseLocalProcessNetworkScope to lock the contract.
Example fix
// before
const scope = parseLocalProcessNetworkScope("whitelist");
// after
const scope = parseLocalProcessNetworkScope("allowlist"); Defensive patterns
Strategy: validation
Validate before calling
const NETWORK_SCOPES = new Set(["deny", "allowlist"]);
function normalizeNetworkScope(value: unknown): "deny" | "allowlist" | null {
if (value == null || value === "") return null;
const legacy = { whitelist: "allowlist", allow: "allowlist", off: "deny", none: "deny" } as Record<string, string>;
const mapped = typeof value === "string" ? (legacy[value] ?? value) : value;
if (typeof mapped !== "string" || !NETWORK_SCOPES.has(mapped)) {
throw new Error(`Unsupported networkScope: ${String(value)}`);
}
return mapped as "deny" | "allowlist";
} Type guard
function isNetworkScope(value: unknown): value is "deny" | "allowlist" {
return value === "deny" || value === "allowlist";
} Try / catch
try {
const scope = parseLocalProcessNetworkScope(config.networkScope);
} catch (error) {
if (error instanceof Error && error.message.startsWith('networkScope must be')) {
throw new ConfigError(`networkScope must be \"deny\" or \"allowlist\" (got: ${String(config.networkScope)})`, { cause: error });
}
throw error;
} Prevention
- Keep an enum/union type for the scope at the config boundary: type NetworkScope = 'deny' | 'allowlist'.
- Translate any legacy vocabulary (whitelist, allow, off) to the canonical literals at the boundary.
- Lock the contract with a round-trip unit test of every accepted spelling.
When it happens
Trigger: Calling parseLocalProcessNetworkScope with values like "none", "off", "disabled", "allowed", "whitelist" (legacy synonym), boolean true/false, or the integer 0. Any value that survives the null/empty check but fails the strict equality falls through to the throw at local-process-sandbox.ts:154.
Common situations: Migration from an older config vocabulary ("whitelist" -> "allowlist"), typos in YAML keys, env vars read with the wrong case, or a UI dropdown that submits a label instead of the canonical value. Also hit when callers pass "allow" expecting it to mean allowlist.
Related errors
- networkAllowlist[${index}] must be a string.
- networkScope="allowlist" requires at least one valid network
- 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/00bdd8e6f5a6adb0.
Report an issue: GitHub.