Mintplex-Labs/anything-llm · warning
${LOG_PREFIX} ANYTHINGLLM_MAX_RETRIES="${envDefinedMaxRetrie
Error message
${LOG_PREFIX} ANYTHINGLLM_MAX_RETRIES="${envDefinedMaxRetries}" is not a valid non-negative integer — using default ${DEFAULT_MAX_RETRIES}. What it means
AnythingLLM prints this console.warn at boot when patchSdkTimeouts() (server/utils/boot/patchSdkTimeouts.js) cannot parse ANYTHINGLLM_MAX_RETRIES. The value is read from the environment, run through parseInt, and rejected when it is NaN or negative; the boot patch then keeps the built-in default of 0 retries for the undici global dispatcher (Agent with headersTimeout/bodyTimeout) that all LLM provider HTTP calls go through. It is purely advisory — the server keeps starting, just without your custom retry count. Note the check is lenient in other ways: parseInt('3x') and parseInt('3.9') both pass as 3, and an empty/unset value skips the branch entirely.
Source
Thrown at server/utils/boot/patchSdkTimeouts.js:36
const envDefinedMaxRetries = process.env.ANYTHINGLLM_MAX_RETRIES;
let timeoutMs = DEFAULT_TIMEOUT_MS;
let maxRetries = DEFAULT_MAX_RETRIES;
if (envDefinedTimeout) {
const parsed = parseInt(envDefinedTimeout, 10);
if (!Number.isFinite(parsed) || parsed <= 0) {
console.warn(
`${LOG_PREFIX} ANYTHINGLLM_FETCH_TIMEOUT="${envDefinedTimeout}" is not a valid positive integer — using default ${DEFAULT_TIMEOUT_MS}ms.`
);
} else {
timeoutMs = parsed;
}
}
if (envDefinedMaxRetries) {
const parsed = parseInt(envDefinedMaxRetries, 10);
if (!Number.isFinite(parsed) || parsed < 0) {
console.warn(
`${LOG_PREFIX} ANYTHINGLLM_MAX_RETRIES="${envDefinedMaxRetries}" is not a valid non-negative integer — using default ${DEFAULT_MAX_RETRIES}.`
);
} else {
maxRetries = parsed;
}
}
const humanSecs = `${(timeoutMs / 1000).toFixed(0)}s`;
try {
const { Agent, setGlobalDispatcher } = require("undici");
setGlobalDispatcher(
new Agent({ headersTimeout: timeoutMs, bodyTimeout: timeoutMs })
);
console.log(
`${LOG_PREFIX} undici global dispatcher — headersTimeout & bodyTimeout ${humanSecs}`
);
} catch {
console.warn(View on GitHub (pinned to 3aec848f28)
Solutions
- Set ANYTHINGLLM_MAX_RETRIES to a plain non-negative integer, e.g. ANYTHINGLLM_MAX_RETRIES=3 (no quotes, no units) in .env or the container environment, then restart the server — the patch runs once at boot before provider modules load.
- If you did not intend to configure retries, unset/delete the variable to explicitly use the default of 0.
- Inspect the raw .env entry for stray quotes, spaces, comments on the same line, or a BOM; retype the line if in doubt.
- If you meant to raise the connection deadline instead of retries, use ANYTHINGLLM_FETCH_TIMEOUT (milliseconds, positive integer) — mixing the two up is a common cause of this warning.
Example fix
# before (.env) ANYTHINGLLM_MAX_RETRIES="3 times" ANYTHINGLLM_FETCH_TIMEOUT=2 min # after (.env) ANYTHINGLLM_MAX_RETRIES=3 ANYTHINGLLM_FETCH_TIMEOUT=120000
Defensive patterns
Strategy: validation
Validate before calling
const raw = process.env.ANYTHINGLLM_MAX_RETRIES;
if (raw !== undefined && raw !== "" && !/^\d+$/.test(raw.trim())) {
throw new Error(
`ANYTHINGLLM_MAX_RETRIES must be a non-negative integer, got "${raw}" — fix it before boot.`
);
} Type guard
const isNonNegativeIntString = (v) => {
const t = String(v ?? "").trim();
return /^\d+$/.test(t) && Number.isSafeInteger(Number(t));
}; Prevention
- Keep numeric env values unquoted and unit-free in .env and compose files; never inline comments on the same line.
- Add a strict env-lint step (regex ^\d+$) to CI or a preboot script — the library's parseInt accepts junk like '3x' that your linter should reject.
- Document sibling variables side by side (ANYTHINGLLM_FETCH_TIMEOUT in ms vs ANYTHINGLLM_MAX_RETRIES as a count) so they are not confused.
When it happens
Trigger: Starting the server with ANYTHINGLLM_MAX_RETRIES="three", "-1", "x3", "3 retries", or a value carrying quotes/whitespace/BOM from a .env file or docker-compose.yml environment block. Only non-numeric or negative parses reach the warning; the fetch-timeout sibling variable ANYTHINGLLM_FETCH_TIMEOUT has its own separate check.
Common situations: Typos in .env (ANYTHINGLLM_MAX_RETRIES=3x), copy-pasting quoted values (ANYTHINGLLM_MAX_RETRIES="3") from documentation into compose files, Windows CRLF line endings in .env, or setting -1 intending "unlimited retries". The mistake is silent beyond this one startup line, so retries quietly stay at 0 and flaky provider calls fail where users expected retries.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- No LocalAI Base Path was set.
- No LocalAi token context limit was set.
- No Groq API key was set.
- KoboldCPP must have a valid base path to use for the api.
- KoboldCPP must have a valid model set.
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/58884bb46bd68db7.
Report an issue: GitHub.