bytedance/deer-flow · warning · HTTPException
Only successful assistant runs can be edited and rerun
Error message
Only successful assistant runs can be edited and rerun
What it means
Raised in _require_successful_source_run (HTTP 409) when the located run record's status is not RunStatus.success. Edit-and-rerun only replays runs that completed cleanly; interrupted, error, or in-flight runs are refused because their checkpointed state may be partial.
Source
Thrown at backend/app/gateway/routers/thread_runs.py:600
return str(status) if status is not None else None
async def _require_successful_source_run(thread_id: str, run_id: str, request: Request) -> RunRecord:
run_mgr = get_run_manager(request)
user_id = await get_current_user(request)
record = await run_mgr.get(run_id, user_id=user_id)
if record is None:
# The run-event journal is the authoritative lookup above. This fallback
# only covers recent in-memory/store hydration gaps for the latest turn.
records = await run_mgr.list_by_thread(thread_id, user_id=user_id, limit=20)
record = next((candidate for candidate in records if getattr(candidate, "run_id", None) == run_id), None)
if record is None:
raise HTTPException(status_code=409, detail="Could not find source run for assistant message")
record_thread_id = getattr(record, "thread_id", None)
if isinstance(record_thread_id, str) and record_thread_id and record_thread_id != thread_id:
raise HTTPException(status_code=409, detail="Could not find source run for assistant message")
if _run_status_value(record) != RunStatus.success.value:
raise HTTPException(status_code=409, detail="Only successful assistant runs can be edited and rerun")
return record
async def _find_interrupted_target_run_id(
thread_id: str,
source_human: Any,
request: Request,
) -> str | None:
source_run_id = _message_additional_kwargs(source_human).get("run_id")
if not isinstance(source_run_id, str) or not source_run_id:
return None
run_mgr = get_run_manager(request)
user_id = await get_current_user(request)
record = await run_mgr.get(source_run_id, user_id=user_id)
if record is None:
records = await run_mgr.list_by_thread(thread_id, user_id=user_id, limit=20)
record = next(View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Check the run's status via the runs list endpoint and only rerun runs with status 'success'.
- For failed runs, use the normal run/retry path (send a new message) rather than edit-rerun.
- Wait for in-flight runs to finish before initiating edit.
- If a run is stuck in a non-terminal status, cancel/cleanup it first via the runs lifecycle endpoint.
Example fix
// before
await editRerun(threadId, runId, newText);
// after
const run = await getRun(threadId, runId);
if (run.status !== 'success') throw new Error(`Run is ${run.status}; only successful runs can be edited`);
await editRerun(threadId, runId, newText); Defensive patterns
Strategy: validation
Validate before calling
const run = await getRun(threadId, runId);
if (run.status !== 'success') { disableEditAffordance(); return; } Type guard
function isSuccessfulRun(run: {status: string}): boolean {
return run.status === 'success';
} Try / catch
try { await editRerun(threadId, runId, text); } catch (e) { if (e.status === 409 && /successful assistant runs/.test(e.detail)) { notify('This turn did not complete successfully; send a new message instead'); } else throw e; } Prevention
- Only enable Edit on turns whose run succeeded
- Handle failed runs via retry/send, not edit-rerun
When it happens
Trigger: Rerunning a run whose status is 'error' (model failure), 'interrupted' (human-in-the-loop pause or cancel), or still running.
Common situations: User retries a failed run via the edit endpoint instead of a normal retry; editing a turn whose previous run was cancelled; racing a still-streaming run.
Related errors
- Checkpoint is missing checkpoint_id
- Only the latest completed user turn can be edited
- Only completed assistant text turns can be edited
- Could not find source run for assistant message
- Could not safely resolve the checkpoint before the target us
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/cf0651321ad3a128.
Report an issue: GitHub.