paperclipai/paperclip · error

networkAllowlist[${index}] must not be empty.

Error message

networkAllowlist[${index}] must not be empty.

What it means

Thrown by parseNetworkAllowlistEntry when an entry in the networkAllowlist array is empty or consists only of whitespace. Each entry must be a hostname, hostname:port, or origin URL; an empty string is rejected immediately before any URL parsing is attempted.

Source

Thrown at packages/adapter-utils/src/local-process-sandbox.ts:123

  let current = path.dirname(candidate);
  while (current !== path.dirname(current)) {
    if (await pathExists(path.join(current, "package.json"))) return current;
    current = path.dirname(current);
  }
  return path.dirname(candidate);
}

async function executableReadPaths(command: string): Promise<string[]> {
  const paths = new Set<string>();
  paths.add(path.dirname(command));
  const realCommand = await fs.realpath(command).catch(() => command);
  paths.add(await nearestPackageRoot(realCommand));
  return Array.from(paths);
}

function parseNetworkAllowlistEntry(entry: string, index: number): NetworkAllowlistRule {
  const trimmed = entry.trim();
  if (!trimmed) throw new Error(`networkAllowlist[${index}] must not be empty.`);
  let hostname: string;
  let port: string | null;
  try {
    const parsed = new URL(trimmed.includes("://") ? trimmed : `https://${trimmed}`);
    if (parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
      throw new Error("path");
    }
    hostname = parsed.hostname.toLowerCase();
    port = parsed.port || null;
  } catch {
    throw new Error(`networkAllowlist[${index}] must be a hostname, hostname:port, or origin URL.`);
  }
  if (!hostname || hostname === "*" || hostname.startsWith("*.")) {
    throw new Error(`networkAllowlist[${index}] must use an exact hostname; wildcards are not supported.`);
  }
  return { hostname, port };
}

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Filter out empty/whitespace entries from the networkAllowlist array before passing it.
  2. Fix the configuration source to not produce empty entries (remove trailing commas, fix env var substitution).
  3. Validate the allowlist array with parseLocalProcessNetworkAllowlist during config loading and report errors to the user.

Example fix

// before
const allowlist = ["api.example.com", "", "registry.npmjs.org"];
const parsed = parseLocalProcessNetworkAllowlist(allowlist);
// after
const allowlist = ["api.example.com", "registry.npmjs.org"].filter((e) => e.trim().length > 0);
const parsed = parseLocalProcessNetworkAllowlist(allowlist);
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeNetworkAllowlist(entries: unknown[]): string[] {
  return entries
    .filter((e): e is string => typeof e === "string" && e.trim().length > 0)
    .map((e) => e.trim());
}
// Use before parseLocalProcessNetworkAllowlist
const cleaned = sanitizeNetworkAllowlist(rawAllowlist);

Type guard

function isNonEmptyString(value: unknown): value is string {
  return typeof value === "string" && value.trim().length > 0;
}

Prevention

When it happens

Trigger: Calling parseLocalProcessNetworkAllowlist with an array that contains an empty string or whitespace-only element, e.g. ['example.com', '', 'api.example.com:443']. The parseNetworkAllowlistEntry function trims the entry and finds it empty.

Common situations: A trailing comma in a configuration list produces an empty element; a template/env-var substitution yields an empty string for one entry; the allowlist is built from user input without filtering blanks.

Related errors


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