danny-avila/LibreChat · error · Error
[waitForRun] ${runIdLog} | Run retrieval failed after ${maxR
Error message
[waitForRun] ${runIdLog} | Run retrieval failed after ${maxRetries} attempts What it means
Thrown by waitForRun in Runs/handle.js after the inner retry loop exhausts maxRetries (5) attempts at retrieving the run from the OpenAI Assistants API without ever obtaining an updatedRun. Each attempt wraps retrieveRun in a 3-second withTimeout; all five attempts either threw or timed out, so the run status is unknowable and polling cannot continue safely.
Source
Thrown at api/server/services/Runs/handle.js:111
raceTimeoutMs,
`[heartbeat ${i}] ${runIdLog} | Run retrieval timed out after ${raceTimeoutMs} ms. Trying again (attempt ${
attempt + 1
} of ${maxRetries})...`,
);
const endTime = Date.now();
logger.debug(
`[heartbeat ${i}] ${runIdLog} | Elapsed run retrieval time: ${endTime - startTime}`,
);
} catch (error) {
attempt++;
startTime = Date.now();
logger.warn(`${runIdLog} | Error retrieving run status`, error);
}
}
if (!updatedRun) {
const errorMessage = `[waitForRun] ${runIdLog} | Run retrieval failed after ${maxRetries} attempts`;
throw new Error(errorMessage);
}
run = updatedRun;
attempt = 0;
const runStatus = `${runInfo} | status: ${run.status}`;
if (run.status !== lastSeenStatus) {
logger.debug(`[${run.status}] ${runInfo}`);
lastSeenStatus = run.status;
}
logger.debug(`[heartbeat ${i}] ${runStatus}`);
let cancelStatus;
try {
const timeoutMessage = `[heartbeat ${i}] ${runIdLog} | Cancel Status check operation timed out.`;
cancelStatus = await withTimeout(cache.get(cacheKey), raceTimeoutMs, timeoutMessage);
} catch (error) {View on GitHub (pinned to 5ff282f900)
Solutions
- Check the OpenAI API status page and the application's network egress (DNS, proxy, firewall).
- Verify openai.apiKey is valid and the organization is in good standing (test with a direct curl to /v1/threads).
- Increase maxRetries and/or raceTimeoutMs if the failures are transient and you can afford longer polling.
- Inspect the warn-level logs ('Error retrieving run status') emitted per attempt — they carry the underlying error that all five attempts shared.
Example fix
// before
async function waitForRun({ openai, run_id, thread_id, runManager }) { /* default maxRetries=5, raceTimeoutMs=3000 */ }
// after (caller)
try {
await waitForRun({ openai, run_id, thread_id, runManager });
} catch (err) {
if (err.message.includes('Run retrieval failed after')) {
// surface to user, do not auto-retry blindly
return { error: 'Assistant run is unreachable right now. Please try again.' };
}
throw err;
} Defensive patterns
Strategy: retry
Validate before calling
if (!openai?.apiKey || !thread_id || !run_id) {
throw new Error('Cannot wait for run: missing apiKey, thread_id, or run_id');
} Try / catch
try {
await waitForRun({ openai, run_id, thread_id, runManager });
} catch (err) {
if (err.message.includes('Run retrieval failed after')) {
// notify user; do not blind-retry the same run indefinitely
return { error: 'Assistant run is unreachable. Please retry.' };
}
throw err;
} Prevention
- Verify apiKey/baseURL and network egress before starting a run.
- Surface per-attempt warn logs to diagnose the underlying cause.
- Distinguish transient outages from configuration errors before retrying.
When it happens
Trigger: OpenAI API outage or sustained 5xx; network partition blocking egress to the API base URL; invalid/expired apiKey producing consistent 401s; wrong baseURL pointing at a non-Assistants endpoint; thread_id/run_id that does not exist on the upstream; a proxy under heavy load timing out every request within 3s.
Common situations: Rate limiting (429) sustained across all retries; a self-hosted/proxy baseURL misconfigured; an OpenAI organization suspension; transient DNS failures in the deployment.
Related errors
- [waitForRun] ${runInfo} | status: ${run.status} | timed out
- [retrieveRun] Failed to retrieve run data:
- [${req.baseUrl}] Invalid version: ${version}
- Unexpected run status ${run.status}.\nFull run info:\n\n${ru
- no_user_key
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/969064eda3d60501.
Report an issue: GitHub.