{"record":{"id":"8b0ce993d3b55594","repo":"bytebase/bytebase","slug":"coderesourceexhausted","errorCode":"CodeResourceExhausted","errorMessage":"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","messagePattern":"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 (.+?)-day window","errorType":"error_code","errorClass":null,"httpStatus":429,"severity":"warning","filePath":"backend/api/v1/release_service_check.go","lineNumber":243,"sourceCode":"func (s *ReleaseService) touchVCSProviderUser(ctx context.Context, workspaceID string, vcsUser *v1pb.VCSUser) error {\n\tif vcsUser == nil {\n\t\treturn nil\n\t}\n\tuserName := truncateVCSProviderUserMetadata(vcsUser.GetUserName())\n\tdisplayName := truncateVCSProviderUserMetadata(vcsUser.GetDisplayName())\n\tok, err := s.store.TouchVCSProviderUser(ctx, workspaceID, &store.VCSProviderUserMessage{\n\t\tVCSType: vcsUser.GetVcsType(),\n\t\tUserID:  vcsUser.GetUserId(),\n\t\tPayload: &storepb.VCSProviderUserPayload{\n\t\t\tUserName:    userName,\n\t\t\tDisplayName: displayName,\n\t\t},\n\t}, vcsProviderUserActiveWindow, s.license.GetUserLimit(ctx, workspaceID))\n\tif err != nil {\n\t\treturn connect.NewError(connect.CodeInternal, errors.Wrap(err, \"failed to touch VCS provider user\"))\n\t}\n\tif !ok {\n\t\treturn 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))\n\t}\n\treturn nil\n}\n\nconst maxVCSProviderUserFieldLength = 256\n\nfunc validateVCSProviderUser(vcsUser *v1pb.VCSUser) error {\n\tif vcsUser == nil {\n\t\treturn nil\n\t}\n\tif vcsUser.GetVcsType() == v1pb.VCSType_VCS_TYPE_UNSPECIFIED {\n\t\treturn connect.NewError(connect.CodeInvalidArgument, errors.New(\"vcs_user.vcs_type is required\"))\n\t}\n\tif _, ok := v1pb.VCSType_name[int32(vcsUser.GetVcsType())]; !ok {\n\t\treturn connect.NewError(connect.CodeInvalidArgument, errors.Errorf(\"vcs_user.vcs_type %d is invalid\", vcsUser.GetVcsType()))\n\t}\n\tif vcsUser.GetUserId() == \"\" {\n\t\treturn connect.NewError(connect.CodeInvalidArgument, errors.New(\"vcs_user.user_id is required\"))","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/api/v1/release_service_check.go#L225-L261","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"activeCount := countActiveVCSUsers(workspaceID, window)\nif activeCount >= licenseUserLimit(workspaceID) {\n    return errors.New(\"license user limit reached before sending vcs_user\")\n}","typeGuard":null,"tryCatchPattern":"if connect.CodeOf(err) == connect.CodeResourceExhausted {\n    // alert operator to raise license limit or reuse existing identity\n}","preventionTips":["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"],"tags":["license","quota","vcs","resource-exhausted"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}