bytebase/bytebase · error
invalid empty workload identity identifier
Error message
invalid empty workload identity identifier
What it means
extractEmailFromUserIdentifier also handles workloadIdentities/{email} identifiers. When the workloadIdentities/ prefix is present but no email follows, it returns "invalid empty workload identity identifier". Without the email the workload identity principal cannot be resolved, so the identifier is rejected; identifiers matching none of the three prefixes get the distinct "invalid user identifier format" error instead.
Source
Thrown at backend/utils/utils.go:235
func extractEmailFromUserIdentifier(identifier string) (string, error) {
if strings.HasPrefix(identifier, common.UserNamePrefix) {
email := strings.TrimPrefix(identifier, common.UserNamePrefix)
if email == "" {
return "", errors.New("invalid empty user identifier")
}
return email, nil
}
if strings.HasPrefix(identifier, common.ServiceAccountNamePrefix) {
email := strings.TrimPrefix(identifier, common.ServiceAccountNamePrefix)
if email == "" {
return "", errors.New("invalid empty service account identifier")
}
return email, nil
}
if strings.HasPrefix(identifier, common.WorkloadIdentityNamePrefix) {
email := strings.TrimPrefix(identifier, common.WorkloadIdentityNamePrefix)
if email == "" {
return "", errors.New("invalid empty workload identity identifier")
}
return email, nil
}
return "", errors.Errorf("invalid user identifier format: %s", identifier)
}
// formatMemberNameByType returns the appropriate member name format based on user type.
// For regular users: users/{email}
// For service accounts: serviceAccounts/{email}
// For workload identities: workloadIdentities/{email}
func formatMemberNameByType(user *store.UserMessage) string {
return common.FormatPrincipalMember(user.Email, user.Type)
}
View on GitHub (pinned to 1870550677)
Solutions
- Correct the workload identity binding so it carries the full "workloadIdentities/{email}" value, or delete the incomplete grant.
- Guard before the call: ensure strings.TrimPrefix(id, common.WorkloadIdentityNamePrefix) is non-empty.
- Fix the provisioning step that writes the identity so the email is always populated before the binding is created.
Example fix
// before
UpdateProjectPolicyFromRoleGrantIssue(ctx, "workloadIdentities/" + wi.Email)
// after
if wi.Email == "" {
return fmt.Errorf("workload identity %s has no email yet; defer policy update", wi.Name)
}
UpdateProjectPolicyFromRoleGrantIssue(ctx, common.WorkloadIdentityNamePrefix + wi.Email) Defensive patterns
Strategy: validation
Validate before calling
func hasNonEmptyWorkloadIdentityEmail(id string) bool {
return strings.HasPrefix(id, "workloadIdentities/") && strings.TrimPrefix(id, "workloadIdentities/") != ""
} Try / catch
email, err := extractEmailFromUserIdentifier(identifier)
if err != nil {
log.Printf("unresolvable workload identity %q: %v", identifier, err)
return nil
} Prevention
- Defer binding creation until the workload identity's email is assigned
- Validate identifiers on ingest from external IdP syncs
- Keep identifiers as full strings in a single field to avoid truncation bugs
When it happens
Trigger: UpdateProjectPolicyFromRoleGrantIssue processing a role grant whose member is the literal string "workloadIdentities/" with an empty email segment.
Common situations: Provisioning pipelines that create workload identity bindings before the identity's email is assigned; external IdP sync writing placeholder identifiers; truncation when identifiers are stored in fixed-width columns or logs.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- invalid empty user identifier
- invalid empty service account identifier
- INVALID_ARGUMENT
- ssl_cert and ssl_key must be both set or unset
- no valid CERTIFICATE PEM block found
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/d061406a3d73d680.
Report an issue: GitHub.