goharbor/harbor · error · lib/errors.Error
BadRequestCode
BadRequestCode
Error message
cannot be empty
What it means
Label.Valid() (called from the POST/PUT /api/v2.0/labels and /api/v2.0/projects/{project_id}/labels handlers) rejects a label whose Name is empty. The check is len(l.Name) == 0, so a missing or whitespace-only-as-empty name fails; it maps to BadRequestCode (HTTP 400).
Source
Thrown at src/pkg/label/model/model.go:48
// Label holds information used for a label
type Label struct {
ID int64 `orm:"pk;auto;column(id)" json:"id"`
Name string `orm:"column(name)" json:"name"`
Description string `orm:"column(description)" json:"description"`
Color string `orm:"column(color)" json:"color"`
Level string `orm:"column(level)" json:"-"`
Scope string `orm:"column(scope)" json:"scope"`
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
CreationTime time.Time `orm:"column(creation_time);auto_now_add" json:"creation_time"`
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
Deleted bool `orm:"column(deleted)" json:"deleted"`
}
// Valid ...
func (l *Label) Valid() error {
if len(l.Name) == 0 {
return errors.New("cannot be empty").WithCode(errors.BadRequestCode)
}
if len(l.Name) > 128 {
return errors.New("max length is 128").WithCode(errors.BadRequestCode)
}
if l.Scope != common.LabelScopeGlobal && l.Scope != common.LabelScopeProject {
return errors.New(nil).WithMessagef("invalid: %s", l.Scope).WithCode(errors.BadRequestCode)
} else if l.Scope == common.LabelScopeProject && l.ProjectID <= 0 {
return errors.New(nil).WithMessagef("invalid: %d", l.ProjectID).WithCode(errors.BadRequestCode)
}
return nil
}
// TableName ...
func (l *Label) TableName() string {
return "harbor_label"
}
View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Provide a non-empty name in the request body, e.g. {"name": "critical", "scope": "g"}.
- Validate/trim the name client-side before calling the API.
- If it comes from a template, assert the templating produced a non-empty value.
Example fix
# before
curl -X POST https://harbor/api/v2.0/labels -d '{"scope": "g"}'
# after
curl -X POST https://harbor/api/v2.0/labels -d '{"name": "critical", "scope": "g", "color": "#FFFFFF"}' Defensive patterns
Strategy: validation
Validate before calling
function validateLabelPayload(l) {
if (!l || typeof l.name !== 'string' || l.name.trim().length === 0)
throw new Error('label name must be a non-empty string');
return true;
} Try / catch
On HTTP 400 from the labels API, log the request body minus secrets, fill the missing name field, and re-send; do not blind-retry unchanged.
Prevention
- Make label name a required field in client schemas/forms.
- Assert non-empty values after templating config files that carry label names.
- Unit-test client payload builders with empty-input cases.
When it happens
Trigger: POST or PUT to the label APIs with the "name" field omitted, set to "", or an empty string after JSON decoding; also direct model.Valid() calls in Go code that build a Label without a Name.
Common situations: Automation templates with a placeholder label name never filled in; YAML/JSON config that drops the name key after templating; API clients with optional-name structs that serialize as empty.
Related errors
- invalid json request
- 10013
- File {} not exist
- Internal dir for tls {} not exist
- Port number in metrics is not valid
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/dcdcbb5884c489e2.
Report an issue: GitHub.