plandex-ai/plandex · warning

Only the plan owner can delete a plan

Error message

Only the plan owner can delete a plan

What it means

DeletePlanHandler returns this 403 when the authenticated user is not the plan's owner. Even after passing authorizePlanDelete (org/project level permission), the handler enforces that only plan.OwnerId may delete the plan. This is an intentional authorization policy, surfaced as a plain-text 403.

Source

Thrown at app/server/handlers/plans_crud.go:229

	auth := Authenticate(w, r, true)
	if auth == nil {
		return
	}

	vars := mux.Vars(r)
	planId := vars["planId"]

	log.Println("planId: ", planId)

	plan := authorizePlanDelete(w, planId, auth)

	if plan == nil {
		return
	}

	if plan.OwnerId != auth.User.Id {
		log.Println("Only the plan owner can delete a plan")
		http.Error(w, "Only the plan owner can delete a plan", http.StatusForbidden)
		return
	}

	res, err := db.Conn.Exec("DELETE FROM plans WHERE id = $1", planId)

	if err != nil {
		log.Printf("Error deleting plan: %v\n", err)
		http.Error(w, "Error deleting 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
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Delete using credentials of the plan owner
  2. Transfer plan ownership to the operating account first (update owner_id via a transfer flow or SQL migration)
  3. Reassign ownership during offboarding so plans remain manageable
  4. If admins should be able to delete, change the handler check to allow org admins — as a policy change, not a client workaround

Example fix

// before
if plan.OwnerId != auth.User.Id { /* 403 always for admins */ }
// after
if plan.OwnerId != auth.User.Id && !auth.IsAdmin {
	
}
// (server-side policy change; clients must still use an authorized token)
Defensive patterns

Strategy: validation

Validate before calling

if plan.OwnerId != currentUser.Id { return errors.New("only the plan owner can delete this plan") }

Try / catch

resp, err := client.DeletePlan(planId)
if apiErr, ok := asApiError(resp, err); ok && resp.StatusCode == 403 {
	// inform the user they need the owner's credentials or an ownership transfer
}

Prevention

When it happens

Trigger: Authenticated non-owner member calls the DELETE plan endpoint on a teammate's plan; an admin token attempts deletion of a user-created plan without being the owner; ownership never reassigned after the creator left the org.

Common situations: Team cleanup scripts running under a shared admin account failing on user-owned plans; former employee's plans frozen because nobody else can delete them; automation using one service account for all org operations.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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