plandex-ai/plandex · warning

Project not found:

Error message

Project not found: 

What it means

This HTTP 404 response means the rename UPDATE executed fine but affected zero rows — no project exists with the given projectId (or the row already had that exact name in some edge interpretations, though for Postgres an UPDATE that matches no id reports 0). The handler uses RowsAffected == 0 to detect a missing project and reports 404 with the projectId included.

Source

Thrown at app/server/handlers/projects.go:222

	res, err := db.Conn.Exec("UPDATE projects SET name = $1 WHERE id = $2", requestBody.Name, projectId)

	if err != nil {
		log.Printf("Error updating project: %v\n", err)
		http.Error(w, "Error updating project: "+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.Printf("Project not found: %v\n", projectId)
		http.Error(w, "Project not found: "+projectId, http.StatusNotFound)
		return
	}

	log.Println("Successfully renamed project", projectId)

}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Confirm the projectId exists: SELECT * FROM projects WHERE id = '<id>'; with the app's DB credentials.
  2. Refresh the client's project list after deletions and remove stale references.
  3. Validate/normalize the projectId (UUID format, trimming) before sending.
  4. Verify the server is pointed at the environment you expect (DATABASE_URL) — the record may exist in a different DB.
  5. On 404, have the client surface 'project no longer exists' and offer to refresh the list.

Example fix

// before (client)
await api.renameProject(projectIdFromCache, name); // may 404 if deleted elsewhere
// after
const project = await api.getProject(projectId);
if (!project) {
  ui.refreshProjectList();
  throw new Error('Project no longer exists');
}
await api.renameProject(projectId, name);
Defensive patterns

Strategy: validation

Validate before calling

// client-side: verify the project exists before renaming
const project = await api.getProject(projectId);
if (!project) { ui.refreshProjectList(); return; } // don't attempt rename

Type guard

function projectExists(p) { return p !== null && typeof p === 'object' && typeof p.id === 'string' && p.id.length > 0; }

Try / catch

// client
try {
  const res = await renameProject(id, name);
  if (res.status === 404) {
    ui.notify('Project no longer exists');
    await ui.refreshProjectList();
  }
} catch (e) { console.error(e); }

Prevention

When it happens

Trigger: Calling the rename endpoint with a projectId that does not exist in the projects table; stale ID from a deleted project still cached in the UI; wrong ID type/format silently coerced (e.g. string with whitespace or wrong UUID) matching nothing; ID belongs to a different environment's database.

Common situations: Frontend holding a project that another user deleted (no realtime sync); test fixtures pointing at a cleaned database; dev/staging database mismatch where the ID exists locally but not on the server; ID truncated or URL-encoded incorrectly in the client.

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/82af4ab31f6db550. Report an issue: GitHub.