bytebase/bytebase · warning
CodeResourceExhausted
CodeResourceExhausted
Error message
new VCS user would exceed the license user limit; increase the license user limit or wait for inactive VCS users to age out of the %d-day window
What it means
touchVCSProviderUser returns CodeResourceExhausted when adding/refreshing a new VCS provider user would push the workspace over its license user limit, counting only users active within the rolling window (vcsProviderUserActiveWindow). The message directs the operator to raise the limit or let inactive VCS users age out.
Source
Thrown at backend/api/v1/release_service_check.go:243
func (s *ReleaseService) touchVCSProviderUser(ctx context.Context, workspaceID string, vcsUser *v1pb.VCSUser) error {
if vcsUser == nil {
return nil
}
userName := truncateVCSProviderUserMetadata(vcsUser.GetUserName())
displayName := truncateVCSProviderUserMetadata(vcsUser.GetDisplayName())
ok, err := s.store.TouchVCSProviderUser(ctx, workspaceID, &store.VCSProviderUserMessage{
VCSType: vcsUser.GetVcsType(),
UserID: vcsUser.GetUserId(),
Payload: &storepb.VCSProviderUserPayload{
UserName: userName,
DisplayName: displayName,
},
}, vcsProviderUserActiveWindow, s.license.GetUserLimit(ctx, workspaceID))
if err != nil {
return connect.NewError(connect.CodeInternal, errors.Wrap(err, "failed to touch VCS provider user"))
}
if !ok {
return connect.NewError(connect.CodeResourceExhausted, errors.Errorf("new VCS user would exceed the license user limit; increase the license user limit or wait for inactive VCS users to age out of the %d-day window", vcsProviderUserActiveWindowDays))
}
return nil
}
const maxVCSProviderUserFieldLength = 256
func validateVCSProviderUser(vcsUser *v1pb.VCSUser) error {
if vcsUser == nil {
return nil
}
if vcsUser.GetVcsType() == v1pb.VCSType_VCS_TYPE_UNSPECIFIED {
return connect.NewError(connect.CodeInvalidArgument, errors.New("vcs_user.vcs_type is required"))
}
if _, ok := v1pb.VCSType_name[int32(vcsUser.GetVcsType())]; !ok {
return connect.NewError(connect.CodeInvalidArgument, errors.Errorf("vcs_user.vcs_type %d is invalid", vcsUser.GetVcsType()))
}
if vcsUser.GetUserId() == "" {
return connect.NewError(connect.CodeInvalidArgument, errors.New("vcs_user.user_id is required"))View on GitHub (pinned to 1870550677)
Solutions
- Increase the license user limit for the workspace.
- Wait vcsProviderUserActiveWindow days for inactive VCS users to age out, then retry.
- Deactivate or clean up VCS user records for departed developers if tooling permits.
- Reuse an existing active vcs_user identity instead of introducing a new one.
Defensive patterns
Strategy: fallback
Validate before calling
activeCount := countActiveVCSUsers(workspaceID, window)
if activeCount >= licenseUserLimit(workspaceID) {
return errors.New("license user limit reached before sending vcs_user")
} Try / catch
if connect.CodeOf(err) == connect.CodeResourceExhausted {
// alert operator to raise license limit or reuse existing identity
} Prevention
- Track license user consumption against the workspace limit
- Reuse existing active VCS identities instead of minting new ones
- Clean up VCS users for departed developers before the window rolls
- Set alerts as active VCS users approach the license cap
When it happens
Trigger: A VCS-triggered CheckRelease introduces a vcs_user whose user_id has no active record, and active VCS user count already equals license.GetUserLimit for the workspace.
Common situations: Growing team connecting via GitLab/GitHub webhooks on a fixed-seat license; long-lived seat allocation consumed by departed developers' VCS identities still inside the active window; evaluating Bytebase on a trial/free license in a busy org.
Related errors
- activation instance count has reached the limit (%v)
- reached the maximum instance count %d
- license signing not available: private key not configured
- CodeResourceExhausted
- failed to count active VCS provider users
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/8b0ce993d3b55594.
Report an issue: GitHub.