{"record":{"id":"0db95ed01f25c8c7","repo":"paperclipai/paperclip","slug":"networkallowlist-index-must-not-be-empty","errorCode":null,"errorMessage":"networkAllowlist[${index}] must not be empty.","messagePattern":"networkAllowlist\\[(.+?)\\] must not be empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/local-process-sandbox.ts","lineNumber":123,"sourceCode":"  let current = path.dirname(candidate);\n  while (current !== path.dirname(current)) {\n    if (await pathExists(path.join(current, \"package.json\"))) return current;\n    current = path.dirname(current);\n  }\n  return path.dirname(candidate);\n}\n\nasync function executableReadPaths(command: string): Promise<string[]> {\n  const paths = new Set<string>();\n  paths.add(path.dirname(command));\n  const realCommand = await fs.realpath(command).catch(() => command);\n  paths.add(await nearestPackageRoot(realCommand));\n  return Array.from(paths);\n}\n\nfunction parseNetworkAllowlistEntry(entry: string, index: number): NetworkAllowlistRule {\n  const trimmed = entry.trim();\n  if (!trimmed) throw new Error(`networkAllowlist[${index}] must not be empty.`);\n  let hostname: string;\n  let port: string | null;\n  try {\n    const parsed = new URL(trimmed.includes(\"://\") ? trimmed : `https://${trimmed}`);\n    if (parsed.username || parsed.password || parsed.pathname !== \"/\" || parsed.search || parsed.hash) {\n      throw new Error(\"path\");\n    }\n    hostname = parsed.hostname.toLowerCase();\n    port = parsed.port || null;\n  } catch {\n    throw new Error(`networkAllowlist[${index}] must be a hostname, hostname:port, or origin URL.`);\n  }\n  if (!hostname || hostname === \"*\" || hostname.startsWith(\"*.\")) {\n    throw new Error(`networkAllowlist[${index}] must use an exact hostname; wildcards are not supported.`);\n  }\n  return { hostname, port };\n}\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/local-process-sandbox.ts#L105-L141","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Filter out empty/whitespace entries from the networkAllowlist array before passing it.","Fix the configuration source to not produce empty entries (remove trailing commas, fix env var substitution).","Validate the allowlist array with parseLocalProcessNetworkAllowlist during config loading and report errors to the user."],"exampleFix":"// before\nconst allowlist = [\"api.example.com\", \"\", \"registry.npmjs.org\"];\nconst parsed = parseLocalProcessNetworkAllowlist(allowlist);\n// after\nconst allowlist = [\"api.example.com\", \"registry.npmjs.org\"].filter((e) => e.trim().length > 0);\nconst parsed = parseLocalProcessNetworkAllowlist(allowlist);","handlingStrategy":"validation","validationCode":"function sanitizeNetworkAllowlist(entries: unknown[]): string[] {\n  return entries\n    .filter((e): e is string => typeof e === \"string\" && e.trim().length > 0)\n    .map((e) => e.trim());\n}\n// Use before parseLocalProcessNetworkAllowlist\nconst cleaned = sanitizeNetworkAllowlist(rawAllowlist);","typeGuard":"function isNonEmptyString(value: unknown): value is string {\n  return typeof value === \"string\" && value.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Filter empty entries from allowlist arrays before parsing.","Validate allowlist configuration at load time and report errors to the operator.","Use structured config formats (KDL/JSON schema) that reject empty array elements."],"tags":["validation","network","sandbox","local-process-sandbox","adapter-utils"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}