bytedance/deer-flow · info · HTTPException

No feedback found for this run

Error message

No feedback found for this run

What it means

Raised by the DELETE /threads/{thread_id}/runs/{run_id}/feedback endpoint when feedback_repo.delete_by_run() reports that no feedback record exists for the current user on that run. It is a 404 Not Found indicating the delete was a no-op — the user never submitted feedback (or already deleted it). This is an idempotency-report error, not a server failure.

Source

Thrown at backend/app/gateway/routers/feedback.py:109


@router.delete("/{thread_id}/runs/{run_id}/feedback")
@require_permission("threads", "delete", owner_check=True, require_existing=True)
async def delete_run_feedback(
    thread_id: ThreadId,
    run_id: str,
    request: Request,
) -> dict[str, bool]:
    """Delete the current user's feedback for a run."""
    user_id = await get_current_user(request)
    feedback_repo = get_feedback_repo(request)
    deleted = await feedback_repo.delete_by_run(
        thread_id=thread_id,
        run_id=run_id,
        user_id=user_id,
    )
    if not deleted:
        raise HTTPException(status_code=404, detail="No feedback found for this run")
    return {"success": True}


@router.post("/{thread_id}/runs/{run_id}/feedback", response_model=FeedbackResponse)
@require_permission("threads", "write", owner_check=True, require_existing=True)
async def create_feedback(
    thread_id: ThreadId,
    run_id: str,
    body: FeedbackCreateRequest,
    request: Request,
) -> dict[str, Any]:
    """Submit feedback (thumbs-up/down) for a run."""
    if body.rating not in (1, -1):
        raise HTTPException(status_code=400, detail="rating must be +1 or -1")

    user_id = await get_current_user(request)

    # Validate run exists and belongs to thread

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Treat 404 on this endpoint as success in the client (the desired state — no feedback — is achieved) instead of surfacing an error.
  2. Check the current feedback state (GET the run's feedback) before issuing the delete, and disable the delete control when no feedback exists.
  3. If double-deletes are common in your UI, debounce/guard the remove-feedback button while a delete request is in flight.

Example fix

// before
await fetch(`/api/threads/${tid}/runs/${rid}/feedback`, { method: 'DELETE' });
if (!res.ok) throw new Error('delete failed');

// after
const res = await fetch(`/api/threads/${tid}/runs/${rid}/feedback`, { method: 'DELETE' });
if (res.status === 404) { /* already gone — desired state */ }
else if (!res.ok) throw new Error(`delete failed: ${res.status}`);
Defensive patterns

Strategy: validation

Validate before calling

// Only delete when the run currently has the user's feedback
const fb = await getUserFeedbackForRun(threadId, runId);
if (!fb) return { success: true }; // nothing to delete — desired state
await del(`/api/threads/${threadId}/runs/${runId}/feedback`);

Try / catch

try { await del(url); } catch (e) { if (e.status === 404) return OK_ALREADY_GONE; throw e; }

Prevention

When it happens

Trigger: Calling DELETE /api/threads/{thread_id}/runs/{run_id}/feedback when the current user has no feedback row for that run: double-clicking the 'remove feedback' button, deleting feedback the UI already removed, or calling delete before any POST .../feedback was made for that user+run pair.

Common situations: Frontend optimistic UI that sends a delete without first checking local feedback state; stale UI after feedback was deleted in another tab or by a session-expired re-login as a different user; automated test suites deleting the same feedback twice in teardown.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/c45ceeefed1c59e6. Report an issue: GitHub.