{"record":{"id":"c8341a1ba232c9c7","repo":"usebruno/bruno","slug":"invalid-scutil-proxy-output","errorCode":null,"errorMessage":"Invalid scutil --proxy output","messagePattern":"Invalid scutil --proxy output","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/bruno-requests/src/network/system-proxy/utils/macos.ts","lineNumber":23,"sourceCode":"export class MacOSProxyResolver implements ProxyResolver {\n  async detect(opts?: { timeoutMs?: number }): Promise<ProxyConfiguration> {\n    const timeoutMs = opts?.timeoutMs ?? 10000;\n    const execOpts: ExecFileOptions = {\n      timeout: timeoutMs,\n      maxBuffer: 1024 * 1024\n    };\n\n    try {\n      const { stdout } = await execFileAsync('scutil', ['--proxy'], execOpts);\n      return this.parseScutilOutput(stdout);\n    } catch (error) {\n      throw new Error(`macOS proxy detection failed: ${error instanceof Error ? error.message : String(error)}`);\n    }\n  }\n\n  private parseScutilOutput(output: string): ProxyConfiguration {\n    if (typeof output !== 'string') {\n      throw new Error('Invalid scutil --proxy output');\n    }\n\n    const cleanLines = output.split('\\n')\n      .map((line) => line.trim())\n      .filter((line) => line.length > 0);\n\n    const dictStart = cleanLines.findIndex((line) => line.includes('<dictionary>'));\n    if (dictStart === -1) {\n      throw new Error('Invalid scutil --proxy output format');\n    }\n    const config = this.parseConfiguration(cleanLines, dictStart);\n    return this.buildProxyConfiguration(config);\n  }\n\n  private parseConfiguration(lines: string[], startIndex: number): Record<string, any> {\n    const config: Record<string, any> = {};\n    let i = startIndex + 1;\n","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/usebruno/bruno/blob/9bdd81c7bdc57006e5f5ebffb79321a8d979f712/packages/bruno-requests/src/network/system-proxy/utils/macos.ts#L5-L41","documentation":"parseScutilOutput guards against a non-string argument before processing. Because execFileAsync returns a Buffer/string, this is a defensive invariant check; if reached it means the caller passed invalid data into the parser directly.","triggerScenarios":"parseScutilOutput invoked with null, undefined, a number, or a Buffer that was not decoded to a string.","commonSituations":"Effectively unreachable through the normal detect() path; only reachable via direct unit-test invocation with bad input or a future refactor that drops the toString conversion.","solutions":["Ensure any caller passes the string stdout from execFileAsync (call .toString() on Buffers).","In tests, pass valid string fixtures instead of objects."],"exampleFix":"// before\nresolver.parseScutilOutput(bufferFromScutil); // Buffer, not string -> throws\n\n// after\nresolver.parseScutilOutput(bufferFromScutil.toString('utf8'));","handlingStrategy":"type-guard","validationCode":"function ensureString(stdout): string { if (typeof stdout !== 'string') throw new TypeError('scutil output must be a string'); return stdout; }","typeGuard":"function isString(v): v is string { return typeof v === 'string'; }","tryCatchPattern":null,"preventionTips":["Always decode execFile Buffers to UTF-8 before parsing.","Pass real string fixtures in tests."],"tags":["proxy","macos","scutil","validation","defensive"],"backgroundTag":null,"analyzedSha":"9bdd81c7bdc57006e5f5ebffb79321a8d979f712","analyzedAt":"2026-08-13T04:09:25.751Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}