usebruno/bruno · error · Error

pacSource must be provided

Error message

pacSource must be provided

What it means

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.

Source

Thrown at packages/bruno-requests/src/utils/pac-resolver.ts:74

  }

  try {
    const response = await axios.get(pacSource, config);
    return response.data;
  } catch (err: any) {
    if (err.response) throw new Error(`Failed to fetch PAC (${err.response.status})`);
    throw err;
  }
}

export type GetPacResolverParams = {
  pacSource: string;
  httpsAgentRequestFields?: TlsOptions;
  opts?: { cacheTtlMs?: number; timeoutMs?: number };
};

export async function getPacResolver({ pacSource, httpsAgentRequestFields = {}, opts = {} }: GetPacResolverParams): Promise<PacWrapper> {
  if (!pacSource) throw new Error('pacSource must be provided');

  const cacheTtlMs = opts.cacheTtlMs ?? 5 * 60 * 1000;
  let key: string;
  if (pacSource.startsWith('https://')) {
    const caRaw = httpsAgentRequestFields.ca;
    const caHash = caRaw
      ? crypto.createHash('sha256').update(Array.isArray(caRaw) ? caRaw.join('|') : caRaw).digest('hex').slice(0, 16)
      : '';
    key = `url:${pacSource}|ca:${caHash}|ru:${httpsAgentRequestFields.rejectUnauthorized ?? ''}|mv:${httpsAgentRequestFields.minVersion ?? ''}`;
  } else {
    // file:// and http:// — no TLS options involved in fetching
    key = `url:${pacSource}`;
  }
  const now = Date.now();
  const cached = CACHE.get(key);
  if (cached && now - cached.ts < cacheTtlMs) return cached.wrapper;

  const wrapperPromise: Promise<PacWrapper> = (async () => {

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Validate pacSource at the caller before invoking getPacResolver; treat empty as 'no PAC configured' and skip the call.
  2. If the value comes from user input, mark the URL field required in the UI and block submission when empty.
  3. If sourced from systemProxyConfig, guard with a truthiness check before calling.

Example fix

// before
const pac = await getPacResolver({ pacSource: config.pac_url }); // may be undefined

// after
if (!config.pac_url) return null;
const pac = await getPacResolver({ pacSource: config.pac_url });
Defensive patterns

Strategy: validation

Validate before calling

function isNonEmptyString(v) { return typeof v === 'string' && v.trim().length > 0; }
if (!isNonEmptyString(pacSource)) {
  // not an error in the caller — 'no PAC configured'
  return { httpAgent: undefined, httpsAgent: undefined };
}
const pac = await getPacResolver({ pacSource, httpsAgentRequestFields, opts });

Type guard

function isValidPacSource(v) {
  if (typeof v !== 'string' || v.length === 0) return false;
  return /^(file:|https?:|data:)/.test(v);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/df141090c7fc742c. Report an issue: GitHub.