danny-avila/LibreChat · error · Error
Unexpected run status ${run.status}.\nFull run info:\n\n${ru
Error message
Unexpected run status ${run.status}.\nFull run info:\n\n${runInfo} What it means
Thrown when an Assistants API run object has a status the code does not recognize as a terminal or actionable state (e.g. not completed, requires_action, failed, cancelled, expired, in_progress). The full run JSON is appended so the unhandled status can be diagnosed.
Source
Thrown at api/server/services/AssistantService.js:108
} else if (run.status === RunStatus.REQUIRES_ACTION) {
const actions = [];
run.required_action?.submit_tool_outputs.tool_calls.forEach((item) => {
const functionCall = item.function;
const args = JSON.parse(functionCall.arguments);
actions.push({
tool: functionCall.name,
toolInput: args,
toolCallId: item.id,
run_id,
thread_id,
});
});
return actions;
}
const runInfo = JSON.stringify(run, null, 2);
throw new Error(`Unexpected run status ${run.status}.\nFull run info:\n\n${runInfo}`);
}
/**
* Filters the steps to keep only the most recent instance of each unique step.
* @param {RunStep[]} steps - The array of RunSteps to filter.
* @return {RunStep[]} The filtered array of RunSteps.
*/
function filterSteps(steps = []) {
if (steps.length <= 1) {
return steps;
}
const stepMap = new Map();
steps.forEach((step) => {
if (!step) {
return;
}
View on GitHub (pinned to 5ff282f900)
Solutions
- Upgrade to a version of the code that handles the new status returned in runInfo.
- If the status is transient, retry the run fetch/poll after a short delay.
- Inspect runInfo in the logs to identify the exact unhandled status and add a handler.
- Pin the Assistants API version to one whose status set is fully handled.
Defensive patterns
Strategy: validation
Validate before calling
const KNOWN_STATUSES = new Set(['queued','in_progress','requires_action','completed','failed','cancelled','expired','cancelling']);
if (!KNOWN_STATUSES.has(run.status)) {
throw new Error(`Unhandled run status: ${run.status}`);
} Type guard
function isKnownRunStatus(status) {
return ['queued','in_progress','requires_action','completed','failed','cancelled','expired','cancelling'].includes(status);
} Try / catch
try { await processRun(run); }
catch (e) {
if (/Unexpected run status/.test(e.message)) { logger.warn(e.message); await sleep(1000); return pollRun(run.id); }
throw e;
} Prevention
- Keep the Assistants client version aligned with the API version you call.
- Add a default branch that logs and re-polls unknown statuses.
- Pin the API version in production.
When it happens
Trigger: OpenAI introduced a new run status value not yet handled by this version of the code; a polling/processing path received a status like 'cancelling' or a future status mid-flight.
Common situations: API version drift — the provider adds a status after this code shipped; a race where a run transitions to an intermediate state the loop did not expect.
Related errors
- [${req.baseUrl}] Invalid version: ${version}
- no_user_key
- Assistants API key not provided. Please provide it again.
- [waitForRun] ${runIdLog} | Run retrieval failed after ${maxR
- Run cancelled
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/ec0d25356630ca3f.
Report an issue: GitHub.