Skip to content

POST /api/v2.0/projects/{id}/members returns 500 instead of 400 for empty request body #23639

Description

@zhangxiaopeng-zgci

Summary

POST /api/v2.0/projects/{id}/members returns 500 Internal Server Error with message can not get valid member entity when the request body is empty or missing all required fields. It should return 400 Bad Request with a clear validation message.

Steps to reproduce

curl -X POST -u admin:<password> \
  https://<host>/api/v2.0/projects/1/members \
  -H "Content-Type: application/json" \
  -d "{}"

Or with a completely empty body:

curl -X POST -u admin:<password> \
  https://<host>/api/v2.0/projects/1/members

Expected behavior

Return 400 Bad Request with a descriptive message, e.g.:

{
  "errors": [{
    "code": "BAD_REQUEST",
    "message": "at least one of member_user or member_group must be provided"
  }]
}

Actual behavior

Returns 500 Internal Server Error:

can not get valid member entity, request: {ProjectID:0 Role:0 MemberUser:{UserID:0 Username:} MemberGroup:{ID:0 GroupName: GroupType:0 LdapGroupDN:}}

Root cause

In src/controller/member/controller.go, the Create() function (line 122) does not validate the request at entry. When all fields in Request are zero-valued, none of the if/else if branches match, member.EntityID stays 0, and the function falls through to:

// line 205
if member.EntityID <= 0 {
    return 0, fmt.Errorf("can not get valid member entity, request: %+v", req)
}

This returns a generic error (not a typed BadRequestError), which surfaces as 500.

Suggested fix

Add early validation at the top of Create():

func (c *controller) Create(ctx context.Context, projectNameOrID any, req Request) (int, error) {
    // ... existing project lookup ...

    if req.MemberUser.UserID == 0 &&
       req.MemberUser.Username == "" &&
       req.MemberGroup.ID == 0 &&
       req.MemberGroup.GroupName == "" &&
       req.MemberGroup.LdapGroupDN == "" {
        return 0, errors.BadRequestError(nil).
            WithMessage("at least one of member_user or member_group must be provided")
    }
    // ... rest of existing logic ...
}

Environment

  • Harbor version: v2.15.2
  • Deployment: HA (2 nodes), external PostgreSQL 15, external Redis 7

Context

Discovered while investigating issue #23608 — the can not get valid member entity error appeared alongside an unrelated retention job failure. Confirmed to be caused by an external script sending empty-body POST requests to the member API.

Reporter: zhangxiaopeng@zgci.ac.cn

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions