can1357/oh-my-pi · error · Error
SearXNG Basic auth requires both searxng.basicUsername and s
Error message
SearXNG Basic auth requires both searxng.basicUsername and searxng.basicPassword, or SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD.
What it means
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.
Source
Thrown at packages/coding-agent/src/web/search/providers/searxng.ts:153
}
/** Build the RFC 7617 Basic auth credential using UTF-8 bytes. */
function buildBasicAuthValue(username: string, password: string): string {
return Buffer.from(`${username}:${password}`, "utf-8").toString("base64");
}
/** RFC 7617 forbids C0 and C1 control characters in Basic auth credentials. */
function hasControlCharacters(value: string): boolean {
return /[\u0000-\u001F\u007F-\u009F]/u.test(value);
}
/** Find SearXNG authentication from settings or environment. Basic auth takes precedence over bearer tokens. */
function findAuth(): SearXNGAuth | null {
const basicUsername = findBasicUsername();
const basicPassword = findBasicPassword();
if (basicUsername !== null || basicPassword !== null) {
if (basicUsername === null || basicPassword === null) {
throw new Error(
"SearXNG Basic auth requires both searxng.basicUsername and searxng.basicPassword, or SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD.",
);
}
if (basicUsername.includes(":")) {
throw new Error("SearXNG Basic auth username cannot contain ':' because RFC 7617 uses it as the separator.");
}
if (hasControlCharacters(basicUsername) || hasControlCharacters(basicPassword)) {
throw new Error("SearXNG Basic auth credentials must not contain RFC 7617 control characters.");
}
return { type: "basic", value: buildBasicAuthValue(basicUsername, basicPassword) };
}
const token = findToken();
return token ? { type: "bearer", value: token } : null;
}
/** Find configured engine names/shortcuts from settings. */
function findEngines(): string | null {View on GitHub (pinned to 9690622007)
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
Example fix
// before SEARXNG_BASIC_USERNAME=alice // after SEARXNG_BASIC_USERNAME=alice SEARXNG_BASIC_PASSWORD=s3cret
Defensive patterns
Strategy: validation
Validate before calling
const u = process.env.SEARXNG_BASIC_USERNAME;
const p = process.env.SEARXNG_BASIC_PASSWORD;
if ((u === undefined) !== (p === undefined)) {
throw new Error('Set both SEARXNG_BASIC_USERNAME and SEARXNG_BASIC_PASSWORD (or neither)');
} Try / catch
try {
const auth = searxngAuth();
} catch (err) {
if (err instanceof Error && err.message.includes("requires both")) {
// fix settings/env pair, or clear the half-set key and use a bearer token
}
throw err;
} Prevention
- 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
When it happens
Trigger: findAuth (called via auth) detects basicUsername !== null XOR basicPassword !== null when locating SearXNG credentials.
Common situations: 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.
Related errors
- SearXNG Basic auth username cannot contain ':' because RFC 7
- Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL
- gitlab-duo-agent
- CoreWeave Serverless Inference requires OpenAI-Project. Set
- An OpenAI API credential is required for file uploads
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a49cc32b7ad7bbca.
Report an issue: GitHub.