{"record":{"id":"969064eda3d60501","repo":"danny-avila/LibreChat","slug":"waitforrun-runidlog-run-retrieval-failed-af","errorCode":null,"errorMessage":"[waitForRun] ${runIdLog} | Run retrieval failed after ${maxRetries} attempts","messagePattern":"\\[waitForRun\\] (.+?) \\| Run retrieval failed after (.+?) attempts","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"api/server/services/Runs/handle.js","lineNumber":111,"sourceCode":"          raceTimeoutMs,\n          `[heartbeat ${i}] ${runIdLog} | Run retrieval timed out after ${raceTimeoutMs} ms. Trying again (attempt ${\n            attempt + 1\n          } of ${maxRetries})...`,\n        );\n        const endTime = Date.now();\n        logger.debug(\n          `[heartbeat ${i}] ${runIdLog} | Elapsed run retrieval time: ${endTime - startTime}`,\n        );\n      } catch (error) {\n        attempt++;\n        startTime = Date.now();\n        logger.warn(`${runIdLog} | Error retrieving run status`, error);\n      }\n    }\n\n    if (!updatedRun) {\n      const errorMessage = `[waitForRun] ${runIdLog} | Run retrieval failed after ${maxRetries} attempts`;\n      throw new Error(errorMessage);\n    }\n\n    run = updatedRun;\n    attempt = 0;\n    const runStatus = `${runInfo} | status: ${run.status}`;\n\n    if (run.status !== lastSeenStatus) {\n      logger.debug(`[${run.status}] ${runInfo}`);\n      lastSeenStatus = run.status;\n    }\n\n    logger.debug(`[heartbeat ${i}] ${runStatus}`);\n\n    let cancelStatus;\n    try {\n      const timeoutMessage = `[heartbeat ${i}] ${runIdLog} | Cancel Status check operation timed out.`;\n      cancelStatus = await withTimeout(cache.get(cacheKey), raceTimeoutMs, timeoutMessage);\n    } catch (error) {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/danny-avila/LibreChat/blob/5ff282f9006c436e561de1afd39a481bea1ef0d8/api/server/services/Runs/handle.js#L93-L129","documentation":"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.","triggerScenarios":"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.","commonSituations":"Rate limiting (429) sustained across all retries; a self-hosted/proxy baseURL misconfigured; an OpenAI organization suspension; transient DNS failures in the deployment.","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."],"exampleFix":"// before\nasync function waitForRun({ openai, run_id, thread_id, runManager }) { /* default maxRetries=5, raceTimeoutMs=3000 */ }\n\n// after (caller)\ntry {\n  await waitForRun({ openai, run_id, thread_id, runManager });\n} catch (err) {\n  if (err.message.includes('Run retrieval failed after')) {\n    // surface to user, do not auto-retry blindly\n    return { error: 'Assistant run is unreachable right now. Please try again.' };\n  }\n  throw err;\n}","handlingStrategy":"retry","validationCode":"if (!openai?.apiKey || !thread_id || !run_id) {\n  throw new Error('Cannot wait for run: missing apiKey, thread_id, or run_id');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await waitForRun({ openai, run_id, thread_id, runManager });\n} catch (err) {\n  if (err.message.includes('Run retrieval failed after')) {\n    // notify user; do not blind-retry the same run indefinitely\n    return { error: 'Assistant run is unreachable. Please retry.' };\n  }\n  throw err;\n}","preventionTips":["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."],"tags":["openai","assistants","network","retry","polling"],"backgroundTag":null,"analyzedSha":"5ff282f9006c436e561de1afd39a481bea1ef0d8","analyzedAt":"2026-08-12T21:38:08.145Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}