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

  1. Use exactly one of the two accepted literals: "deny" or "allowlist".
  2. Map legacy or UI values to the canonical vocabulary before parsing: { whitelist: "allowlist", off: "deny", on: "allowlist" }.
  3. To disable sandbox networking entirely, pass null, undefined, or "" — these return null and the scope is treated as unset.
  4. 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

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


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/00bdd8e6f5a6adb0. Report an issue: GitHub.