makeplane/plane · error · CommandError

User not found

Error message

User not found

What it means

Raised by `create_project_member` when `User.objects.filter(email=user_email).first()` returns None (lines 41-43). No Plane user matches the supplied email. Swallowed by the command's `except CommandError`. Note the filter is case-sensitive and not normalized (no `.lower()`), unlike `reactivate_workspace_member`.

Source

Thrown at apps/api/plane/db/management/commands/create_project_member.py:43

        parser.add_argument("--user_email", type=str, nargs="?", help="User Email")
        parser.add_argument("--role", type=int, nargs="?", help="Role of the user in the project")

    def handle(self, *args: Any, **options: Any):
        try:
            if not options["project_id"]:
                raise CommandError("Project ID is required")
            if not options["user_email"]:
                raise CommandError("User Email is required")

            project_id = options["project_id"]
            user_email = options["user_email"]
            role = options.get("role", 20)

            print(f"Role: {role}")

            user = User.objects.filter(email=user_email).first()
            if not user:
                raise CommandError("User not found")

            # Check if the project exists
            project = Project.objects.filter(pk=project_id).first()
            if not project:
                raise CommandError("Project not found")

            # Check if the user exists in the workspace
            if not WorkspaceMember.objects.filter(workspace=project.workspace, member=user, is_active=True).exists():
                raise CommandError("User not member in workspace")


            if ProjectMember.objects.filter(project=project, member=user).exists():
                # Update the project member
                ProjectMember.objects.filter(project=project, member=user).update(
                    is_active=True, role=role
                )
            else:
                # Create the project member

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Verify the user: `python manage.py shell -c "from plane.db.models import User; print(User.objects.filter(email='user@example.com').exists())"`
  2. Match the exact stored (lowercased) email.
  3. Have the user sign in once to create the record.

Example fix

# before
--user_email User@Example.com   # no match (case-sensitive)
# after
--user_email user@example.com
Defensive patterns

Strategy: validation

Validate before calling

python manage.py shell -c "from plane.db.models import User; import sys; sys.exit(0 if User.objects.filter(email='user@example.com').exists() else 1)"

Type guard

def user_exists(email: str) -> bool:
    from plane.db.models import User
    return User.objects.filter(email=email).exists()

Try / catch

# Command swallows CommandError internally; rely on a pre-check instead.

Prevention

When it happens

Trigger: Passing `--user_email` for someone who has never signed in, or whose stored email casing differs.

Common situations: User not yet registered; casing mismatch; wrong domain.

Related errors


AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12). Data as JSON: /api/errors/02b3cd72202f2410. Report an issue: GitHub.