{"record":{"id":"a49cc32b7ad7bbca","repo":"can1357/oh-my-pi","slug":"searxng-basic-auth-requires-both-searxng-basicuser","errorCode":null,"errorMessage":"SearXNG Basic auth requires both searxng.basicUsername and searxng.basicPassword, or SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD.","messagePattern":"SearXNG Basic auth requires both searxng\\.basicUsername and searxng\\.basicPassword, or SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/web/search/providers/searxng.ts","lineNumber":153,"sourceCode":"}\n\n/** Build the RFC 7617 Basic auth credential using UTF-8 bytes. */\nfunction buildBasicAuthValue(username: string, password: string): string {\n\treturn Buffer.from(`${username}:${password}`, \"utf-8\").toString(\"base64\");\n}\n\n/** RFC 7617 forbids C0 and C1 control characters in Basic auth credentials. */\nfunction hasControlCharacters(value: string): boolean {\n\treturn /[\\u0000-\\u001F\\u007F-\\u009F]/u.test(value);\n}\n\n/** Find SearXNG authentication from settings or environment. Basic auth takes precedence over bearer tokens. */\nfunction findAuth(): SearXNGAuth | null {\n\tconst basicUsername = findBasicUsername();\n\tconst basicPassword = findBasicPassword();\n\tif (basicUsername !== null || basicPassword !== null) {\n\t\tif (basicUsername === null || basicPassword === null) {\n\t\t\tthrow new Error(\n\t\t\t\t\"SearXNG Basic auth requires both searxng.basicUsername and searxng.basicPassword, or SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD.\",\n\t\t\t);\n\t\t}\n\t\tif (basicUsername.includes(\":\")) {\n\t\t\tthrow new Error(\"SearXNG Basic auth username cannot contain ':' because RFC 7617 uses it as the separator.\");\n\t\t}\n\t\tif (hasControlCharacters(basicUsername) || hasControlCharacters(basicPassword)) {\n\t\t\tthrow new Error(\"SearXNG Basic auth credentials must not contain RFC 7617 control characters.\");\n\t\t}\n\t\treturn { type: \"basic\", value: buildBasicAuthValue(basicUsername, basicPassword) };\n\t}\n\n\tconst token = findToken();\n\treturn token ? { type: \"bearer\", value: token } : null;\n}\n\n/** Find configured engine names/shortcuts from settings. */\nfunction findEngines(): string | null {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/web/search/providers/searxng.ts#L135-L171","documentation":"SearXNG Basic auth is configured only partially: exactly one of username/password was found (settings searxng.basicUsername/basicPassword or env SEARXNG_BASIC_USERNAME/SEARXNG_BASIC_PASSWORD). RFC 7617 Basic auth needs both, so findAuth throws a plain Error describing the required pair.","triggerScenarios":"findAuth (called via auth) detects basicUsername !== null XOR basicPassword !== null when locating SearXNG credentials.","commonSituations":"Setting only one of the two settings keys, exporting only one of the two env vars, secrets manager injecting only one value, renaming one key and forgetting the other.","solutions":["Set both searxng.basicUsername and searxng.basicPassword in settings","Or set both SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD env vars","If Basic auth is unintended, remove the half-configured key entirely and configure a bearer token instead"],"exampleFix":"// before\nSEARXNG_BASIC_USERNAME=alice\n// after\nSEARXNG_BASIC_USERNAME=alice\nSEARXNG_BASIC_PASSWORD=s3cret","handlingStrategy":"validation","validationCode":"const u = process.env.SEARXNG_BASIC_USERNAME;\nconst p = process.env.SEARXNG_BASIC_PASSWORD;\nif ((u === undefined) !== (p === undefined)) {\n  throw new Error('Set both SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD (or neither)');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const auth = searxngAuth();\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"requires both\")) {\n    // fix settings/env pair, or clear the half-set key and use a bearer token\n  }\n  throw err;\n}","preventionTips":["Always set Basic auth username and password as a pair","Prefer one credential source (settings OR env) and document it","Validate SearXNG config at startup, not on first search"],"tags":["configuration","auth","searxng","basic-auth","missing-env-var"],"backgroundTag":"incomplete-credentials","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}