{"record":{"id":"3b44ac8f340a888c","repo":"Tencent/WeKnora","slug":"member-limit-must-be-0","errorCode":null,"errorMessage":"member_limit must be >= 0","messagePattern":"member_limit must be >= 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/organization.go","lineNumber":92,"sourceCode":"\treturn &t\n}\n\n// CreateOrganization creates a new organization. The creator's tenant\n// is enrolled at admin role and userID is recorded as the representative.\nfunc (s *organizationService) CreateOrganization(ctx context.Context, userID string, tenantID uint64, req *types.CreateOrganizationRequest) (*types.Organization, error) {\n\tlogger.Infof(ctx, \"Creating organization: %s by user: %s in tenant: %d\", req.Name, userID, tenantID)\n\n\tvalidityDays := DefaultInviteCodeValidityDays\n\tif req.InviteCodeValidityDays != nil {\n\t\tif !ValidInviteCodeValidityDays[*req.InviteCodeValidityDays] {\n\t\t\treturn nil, ErrInvalidValidityDays\n\t\t}\n\t\tvalidityDays = *req.InviteCodeValidityDays\n\t}\n\tmemberLimit := DefaultMemberLimit\n\tif req.MemberLimit != nil {\n\t\tif *req.MemberLimit < 0 {\n\t\t\treturn nil, errors.New(\"member_limit must be >= 0\")\n\t\t}\n\t\tmemberLimit = *req.MemberLimit\n\t}\n\n\tnow := time.Now()\n\torg := &types.Organization{\n\t\tID:          uuid.New().String(),\n\t\tName:        req.Name,\n\t\tDescription: req.Description,\n\t\tAvatar:      strings.TrimSpace(req.Avatar),\n\t\tOwnerID:     userID,\n\t\t// Owning tenant is pinned at create time; never changes even if\n\t\t// the owner user later moves to another tenant. See migration\n\t\t// 000046 and the isOwnerTenant helper below.\n\t\tOwnerTenantID:          tenantID,\n\t\tInviteCode:             generateInviteCode(),\n\t\tInviteCodeExpiresAt:    resolveInviteExpiry(validityDays, now),\n\t\tInviteCodeValidityDays: validityDays,","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/organization.go#L74-L110","documentation":"CreateOrganization rejects a CreateOrganizationRequest whose MemberLimit pointer is non-nil but points to a negative integer. The limit defaults to DefaultMemberLimit when the field is omitted, so only explicit negative values trip this validation. It is a plain errors.New, not a sentinel, so callers must match on message or validate upstream.","triggerScenarios":"Calling CreateOrganization with a request whose MemberLimit is set to any value < 0 (e.g. -1), such as a request body {\"member_limit\": -5} deserialized into *int without server-side range checks.","commonSituations":"Client forms allowing negative inputs, API clients sending 0-means-unlimited conventions from other systems as -1, or misconfigured default values in provisioning scripts.","solutions":["Send a non-negative member_limit (or omit the field to use DefaultMemberLimit).","Validate the value client-side before calling CreateOrganization.","If 0 or negative is meant to mean 'unlimited', clamp it to a large positive value or omit it, since the API does not support unlimited semantics via negatives."],"exampleFix":"// before\nreq := &types.CreateOrganizationRequest{Name: \"acme\", MemberLimit: &negLimit} // negLimit = -1\n// after\nlimit := 100\nif negLimit >= 0 { limit = negLimit }\nreq := &types.CreateOrganizationRequest{Name: \"acme\", MemberLimit: &limit}","handlingStrategy":"validation","validationCode":"if req.MemberLimit != nil && *req.MemberLimit < 0 {\n    return fmt.Errorf(\"member_limit must be >= 0, got %d\", *req.MemberLimit)\n}","typeGuard":"func validMemberLimit(p *int) bool { return p == nil || *p >= 0 }","tryCatchPattern":null,"preventionTips":["Validate member_limit >= 0 in the API handler before the service call.","Reject negative numbers at the form/schema layer (e.g. JSON schema minimum: 0).","Document that omitting member_limit uses DefaultMemberLimit."],"tags":["validation","organization","go","input-validation"],"backgroundTag":"negative-value-validation","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}