plandex-ai/plandex · warning

User does not have permission to update plan

Error message

User does not have permission to update plan

What it means

This 403 is returned by authorizePlanUpdate when the plan exists and the user has access, but the user is neither the plan owner (plan.OwnerId != auth.User.Id) nor holds shared.PermissionUpdateAnyPlan. Update rights are limited to the owner or users with the admin-level update permission.

Source

Thrown at app/server/handlers/auth_helpers.go:698

	if plan == nil {
		log.Println("user doesn't have access the plan")
		http.Error(w, "no access to plan", http.StatusUnauthorized)
		return nil
	}

	return plan
}

func authorizePlanUpdate(w http.ResponseWriter, planId string, auth *types.ServerAuth) *db.Plan {
	plan := authorizePlan(w, planId, auth)

	if plan == nil {
		return nil
	}

	if plan.OwnerId != auth.User.Id && !auth.HasPermission(shared.PermissionUpdateAnyPlan) {
		log.Println("User does not have permission to update plan")
		http.Error(w, "User does not have permission to update plan", http.StatusForbidden)
		return nil
	}

	return plan
}

func authorizePlanDelete(w http.ResponseWriter, planId string, auth *types.ServerAuth) *db.Plan {
	plan := authorizePlan(w, planId, auth)

	if plan == nil {
		return nil
	}

	if plan.OwnerId != auth.User.Id && !auth.HasPermission(shared.PermissionDeleteAnyPlan) {
		log.Println("User does not have permission to delete plan")
		http.Error(w, "User does not have permission to delete plan", http.StatusForbidden)
		return nil
	}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Ask the plan owner to make the change, or to grant PermissionUpdateAnyProject-style update permission (PermissionUpdateAnyPlan) to the user
  2. Have the owner transfer plan ownership to the user who needs to edit
  3. Hide/disable edit controls for non-owners lacking the update permission in the client

Example fix

// before
await api.updatePlan(planId, { name: 'Q3 roadmap' });
// after
if (plan.ownerId !== auth.userId && !auth.permissions.includes('update_any_plan')) {
  throw new Error('Only the plan owner or admins can update this plan');
}
await api.updatePlan(planId, { name: 'Q3 roadmap' });
Defensive patterns

Strategy: type-guard

Validate before calling

function canUpdatePlan(plan, auth) {
  return plan.ownerId === auth.userId || auth.permissions.includes('update_any_plan');
}

Type guard

function isPlanOwner(plan, auth) {
  return typeof plan?.ownerId === 'string' && plan.ownerId === auth?.userId;
}

Try / catch

try {
  return await api.updatePlan(planId, patch);
} catch (e) {
  if (e.status === 403 && /permission to update plan/.test(e.body)) {
    notifyUser('Only the plan owner or admins can update this plan');
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: A non-owner member without PermissionUpdateAnyPlan calls a plan-update endpoint (via authorizePlanUpdate) — editing plan content, settings, or metadata on someone else's plan.

Common situations: A teammate tries to edit another user's plan; ownership was transferred and the old collaborator's edits now fail; UI renders edit controls without checking ownership/permission.

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/03dac26ea6169866. Report an issue: GitHub.