ruvnet/ruflo · error · Error
User not found
Error message
User not found
What it means
task_update (simple implementation) starts with taskStore.get(input.taskId); a missing entry throws 'Task not found: <id>'. The store is the same process-local Map filled by task_create, and this handler runs only after an orchestrator attempt failed (visible as 'Failed to update task via orchestrator:' in server logs). Updates themselves are guarded separately: completed/cancelled tasks cannot be modified (error 1138), but a missing task never gets that far.
Solutions
- Re-create the task after a restart and update the new ID
- Verify the ID via task list or task_status before calling task_update
- If server logs show the orchestrator update failing, restore the orchestrator connection — the task may exist there but not in the local fallback
- Track taskId -> status in your own state and discard IDs from dead processes
Example fix
// before
await client.callTool('task_update', { taskId, priority: 1 }); // stale id -> throws [1137]
// after
const { tasks } = await client.callTool('task_list', { status: 'all' });
const live = tasks.find(t => t.description === originalDescription);
if (!live) throw new Error('task lost to restart; re-create it');
await client.callTool('task_update', { taskId: live.id, priority: 1 }); Defensive patterns
Strategy: validation
Validate before calling
const { tasks } = await client.callTool('task_list', { status: 'all' });
const updatable = tasks.find(t => t.id === taskId && t.status !== 'completed' && t.status !== 'cancelled');
if (!updatable) throw new Error(`task ${taskId} missing or frozen`); Try / catch
try {
await client.callTool('task_update', { taskId, priority });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Task not found')) {
// store reset — re-create if this update still matters, otherwise drop it
} else throw e;
} Prevention
- Update tasks in the process that created them; re-create after restarts
- Batch your edits before a task reaches a terminal state
- Distinguish this not-found from the frozen-status error (1138) — they need different handling
When it happens
Trigger: Updating a task whose ID predates a server restart; orchestrator path failed and local store lacks the task; passing the wrong field as taskId (e.g. a dependency's ID); updating a task created in another coordinator instance.
Common situations: Long-lived agents that remember taskIds across server recycles; scripts editing tasks by hardcoded IDs; hybrid setups where some tasks live only in the orchestrator and the orchestrator connection drops mid-update.
Related errors
- SSRF guard: private/loopback host rejected
- Failed to create share link
- JSON.stringify(response.error)
- SSRF guard: only HTTPS URLs are permitted, got
- SSRF guard: private/loopback host rejected
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/b77c5636d7439ff1.
Report an issue: GitHub.
Appendix: source
Thrown at ruflo/src/ruvocal/src/lib/server/auth.ts:467
token: result.oauth?.token?.value,
sessionId,
secretSessionId,
isAdmin: result.user?.isAdmin || adminTokenManager.isAdmin(sessionId),
};
}
if (isApi) {
const authorization = headers.get("Authorization");
if (authorization?.startsWith("Bearer ")) {
const token = authorization.slice(7);
const hash = await sha256(token);
sessionId = secretSessionId = hash;
const cacheHit = await collections.tokenCaches.findOne({ tokenHash: hash });
if (cacheHit) {
const user = await collections.users.findOne({ hfUserId: cacheHit.userId });
if (!user) {
throw new Error("User not found");
}
return {
user,
sessionId,
token,
secretSessionId,
isAdmin: user.isAdmin || adminTokenManager.isAdmin(sessionId),
};
}
const response = await fetch("https://huggingface.co/api/whoami-v2", {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) {
throw new Error("Unauthorized");
}
View on GitHub (pinned to fa13ee4ad6)