{"record":{"id":"df141090c7fc742c","repo":"usebruno/bruno","slug":"pacsource-must-be-provided","errorCode":null,"errorMessage":"pacSource must be provided","messagePattern":"pacSource must be provided","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-requests/src/utils/pac-resolver.ts","lineNumber":74,"sourceCode":"  }\n\n  try {\n    const response = await axios.get(pacSource, config);\n    return response.data;\n  } catch (err: any) {\n    if (err.response) throw new Error(`Failed to fetch PAC (${err.response.status})`);\n    throw err;\n  }\n}\n\nexport type GetPacResolverParams = {\n  pacSource: string;\n  httpsAgentRequestFields?: TlsOptions;\n  opts?: { cacheTtlMs?: number; timeoutMs?: number };\n};\n\nexport async function getPacResolver({ pacSource, httpsAgentRequestFields = {}, opts = {} }: GetPacResolverParams): Promise<PacWrapper> {\n  if (!pacSource) throw new Error('pacSource must be provided');\n\n  const cacheTtlMs = opts.cacheTtlMs ?? 5 * 60 * 1000;\n  let key: string;\n  if (pacSource.startsWith('https://')) {\n    const caRaw = httpsAgentRequestFields.ca;\n    const caHash = caRaw\n      ? crypto.createHash('sha256').update(Array.isArray(caRaw) ? caRaw.join('|') : caRaw).digest('hex').slice(0, 16)\n      : '';\n    key = `url:${pacSource}|ca:${caHash}|ru:${httpsAgentRequestFields.rejectUnauthorized ?? ''}|mv:${httpsAgentRequestFields.minVersion ?? ''}`;\n  } else {\n    // file:// and http:// — no TLS options involved in fetching\n    key = `url:${pacSource}`;\n  }\n  const now = Date.now();\n  const cached = CACHE.get(key);\n  if (cached && now - cached.ts < cacheTtlMs) return cached.wrapper;\n\n  const wrapperPromise: Promise<PacWrapper> = (async () => {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-requests/src/utils/pac-resolver.ts#L56-L92","documentation":"Thrown at the top of getPacResolver when pacSource is falsy (undefined, null, '' or 0). It is a contract guard: the rest of the function builds a cache key and fetches the PAC, both of which require a non-empty source string. The error fires synchronously inside the async function before any cache lookup or network work.","triggerScenarios":"A caller invokes getPacResolver({ pacSource: '' }), passes no pacSource field, or flows an undefined value from config/UI into the call. Also triggered when an upstream caller passes pacSource conditionally (e.g. from systemProxyConfig.get('pac_url')) without checking it was set.","commonSituations":"UI 'Use PAC' checkbox toggled on but the URL field left blank; a config merge that overwrote pac_url with undefined; system proxy detection returning no pac_url yet the code path still calls getPacResolver.","solutions":["Validate pacSource at the caller before invoking getPacResolver; treat empty as 'no PAC configured' and skip the call.","If the value comes from user input, mark the URL field required in the UI and block submission when empty.","If sourced from systemProxyConfig, guard with a truthiness check before calling."],"exampleFix":"// before\nconst pac = await getPacResolver({ pacSource: config.pac_url }); // may be undefined\n\n// after\nif (!config.pac_url) return null;\nconst pac = await getPacResolver({ pacSource: config.pac_url });","handlingStrategy":"validation","validationCode":"function isNonEmptyString(v) { return typeof v === 'string' && v.trim().length > 0; }\nif (!isNonEmptyString(pacSource)) {\n  // not an error in the caller — 'no PAC configured'\n  return { httpAgent: undefined, httpsAgent: undefined };\n}\nconst pac = await getPacResolver({ pacSource, httpsAgentRequestFields, opts });","typeGuard":"function isValidPacSource(v) {\n  if (typeof v !== 'string' || v.length === 0) return false;\n  return /^(file:|https?:|data:)/.test(v);\n}","tryCatchPattern":null,"preventionTips":["Guard every call site with a truthiness check; empty pacSource means 'no PAC', not an exception.","Make the UI field required and validate the scheme (file://, http://, https://) on submit.","Default config fields to undefined rather than '' so the truthiness check is unambiguous.","Centralize PAC-source resolution in one helper to avoid scattered ad-hoc checks."],"tags":["validation","pac","configuration","argument-error"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}