bytebase/bytebase · error
invalid label value %q for key %q: must contain only letters
Error message
invalid label value %q for key %q: must contain only letters, numbers, underscores, and dashes (max 63 chars)
What it means
validateLabels rejects label values not matching ^[a-zA-Z0-9_-]{0,63}$: values may contain letters (any case), digits, underscores, and dashes, up to 63 chars, and may be empty. The error names both the offending value and its key.
Source
Thrown at backend/api/v1/common.go:67
// - Maximum 64 labels allowed
// - Keys must start with lowercase letter, then contain only lowercase letters, numbers, underscores, and dashes (max 63 chars)
// - Values can contain letters, numbers, underscores, and dashes (max 63 chars, can be empty)
func validateLabels(labels map[string]string) error {
if len(labels) > 64 {
return errors.Errorf("maximum 64 labels allowed, got %d", len(labels))
}
// Key pattern: must start with lowercase letter, then lowercase letters, numbers, underscores, dashes (max 63 chars)
keyPattern := `^[a-z][a-z0-9_-]{0,62}$`
// Value pattern: letters, numbers, underscores, dashes (max 63 chars, can be empty)
valuePattern := `^[a-zA-Z0-9_-]{0,63}$`
keyRegex := regexp.MustCompile(keyPattern)
valueRegex := regexp.MustCompile(valuePattern)
for key, value := range labels {
if !keyRegex.MatchString(key) {
return errors.Errorf("invalid label key %q: must start with lowercase letter and contain only lowercase letters, numbers, underscores, and dashes (max 63 chars)", key)
}
if !valueRegex.MatchString(value) {
return errors.Errorf("invalid label value %q for key %q: must contain only letters, numbers, underscores, and dashes (max 63 chars)", value, key)
}
}
return nil
}
type Expression struct {
Key string
Operator OperatorType
Value string
}
// ParseFilter will parse the simple filter.
// TODO(rebelice): support more complex filter.
// Currently we support the following syntax:
// 1. for single expression:
// i. defined as `key comparator "val"`.
// ii. Comparator can be `=`, `!=`, `>`, `>=`, `<`, `<=`.
// iii. If val doesn't contain space, we can omit the double quotes.View on GitHub (pinned to 1870550677)
Solutions
- Replace invalid characters (spaces, slashes, dots) with dashes or underscores
- Truncate values to 63 characters
- Slugify values before assigning them to labels
- Pre-validate values with the same regex on the client
Example fix
// before
labels := map[string]string{"env": "production / eu-west"}
// after
labels := map[string]string{"env": "production-eu-west"} Defensive patterns
Strategy: validation
Validate before calling
var valRe = regexp.MustCompile(`^[a-zA-Z0-9_-]{0,63}$`)
func validLabelValue(v string) bool { return valRe.MatchString(v) } Try / catch
err := client.UpdateProject(ctx, req)
if err != nil && strings.Contains(err.Error(), "invalid label value") {
// slugify/truncate values and retry
} Prevention
- Slugify values (replace spaces/slashes/dots with dashes)
- Truncate values to 63 chars
- Pre-validate with the same regex client-side
- Avoid free-text fields as label values
When it happens
Trigger: CreateInstance/UpdateInstance/CreateProject/UpdateProject with a label value containing spaces, dots, slashes, colons, unicode, or longer than 63 characters.
Common situations: Values copied from URLs or file paths ('prod/eu-west'); emails as values; human-readable values with spaces; team names longer than 63 chars.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- invalid label key %q: must start with lowercase letter and c
- invalid email address
- maximum 64 labels allowed, got %d
- invalid naming rule format pattern %q for rule %s
- invalid domain %q
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/5e748eb1a642d08a.
Report an issue: GitHub.