plandex-ai/plandex · error
Not found
Error message
Not found
What it means
The archive UPDATE ran without error but affected 0 rows, meaning no plan with the given planId existed at UPDATE time; the handler returns HTTP 404 'Not found'. This is a race/consistency check after the state guard passed.
Source
Thrown at app/server/handlers/plans_changes.go:473
res, err := db.Conn.Exec("UPDATE plans SET archived_at = NOW() WHERE id = $1", planId)
if err != nil {
log.Printf("Error archiving plan: %v\n", err)
http.Error(w, "Error archiving plan: "+err.Error(), http.StatusInternalServerError)
return
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Printf("Error getting rows affected: %v\n", err)
http.Error(w, "Error getting rows affected: "+err.Error(), http.StatusInternalServerError)
return
}
if rowsAffected == 0 {
log.Println("Plan not found")
http.Error(w, "Not found", http.StatusNotFound)
return
}
log.Println("Successfully archived plan", planId)
}
func UnarchivePlanHandler(w http.ResponseWriter, r *http.Request) {
auth := Authenticate(w, r, true)
if auth == nil {
return
}
log.Println("Received request for UnarchivePlanHandler")
vars := mux.Vars(r)
planId := vars["planId"]
log.Println("planId: ", planId)
View on GitHub (pinned to e2d772072e)
Solutions
- Verify the planId exists (query plans by id) in the environment you're hitting
- Re-fetch the plan list and retry with a fresh planId
- Check you're pointed at the intended database/environment
- Handle 404 in the client by refreshing plan state rather than retrying
Example fix
// before
await archivePlan('abc123'); // stale id → 404
// after
const plans = await listPlans();
if (plans.some(p => p.id === id)) await archivePlan(id); else refreshList(); Defensive patterns
Strategy: validation
Validate before calling
const plans = await listPlans();
if (!plans.some(p => p.id === planId)) throw new Error(`Plan ${planId} does not exist`);
await archivePlan(planId); Type guard
function planExists(plans, id) { return Array.isArray(plans) && plans.some(p => p && p.id === id); } Try / catch
try { await archivePlan(planId); } catch (e) { if (e.status === 404) { await refreshPlans(); throw new Error('Plan not found — it may have been deleted'); } throw e; } Prevention
- Re-fetch plan ids rather than using cached/stale ones
- Confirm you're targeting the right environment/database
- Handle 404 by refreshing state, not retrying
- Watch for concurrent deletes if multiple operators manage plans
When it happens
Trigger: planId in the URL doesn't match any row in plans (typo, wrong environment, plan deleted between the authorizePlanArchive SELECT and the UPDATE, or the plan was removed by a concurrent operation).
Common situations: Client caching a stale planId after the plan was deleted; archiving against the wrong database/environment (staging vs prod); race with a delete operation; user following an outdated link.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- error getting plan config: %v
- error getting default plan config: %v
- error getting default plan config: %v
- error getting plan: %v
- Error getting org:
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/1ad057a4af1572ab.
Report an issue: GitHub.