Tencent/WeKnora · error

member_limit must be >= 0

Error message

member_limit must be >= 0

What it means

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.

Source

Thrown at internal/application/service/organization.go:92

	return &t
}

// CreateOrganization creates a new organization. The creator's tenant
// is enrolled at admin role and userID is recorded as the representative.
func (s *organizationService) CreateOrganization(ctx context.Context, userID string, tenantID uint64, req *types.CreateOrganizationRequest) (*types.Organization, error) {
	logger.Infof(ctx, "Creating organization: %s by user: %s in tenant: %d", req.Name, userID, tenantID)

	validityDays := DefaultInviteCodeValidityDays
	if req.InviteCodeValidityDays != nil {
		if !ValidInviteCodeValidityDays[*req.InviteCodeValidityDays] {
			return nil, ErrInvalidValidityDays
		}
		validityDays = *req.InviteCodeValidityDays
	}
	memberLimit := DefaultMemberLimit
	if req.MemberLimit != nil {
		if *req.MemberLimit < 0 {
			return nil, errors.New("member_limit must be >= 0")
		}
		memberLimit = *req.MemberLimit
	}

	now := time.Now()
	org := &types.Organization{
		ID:          uuid.New().String(),
		Name:        req.Name,
		Description: req.Description,
		Avatar:      strings.TrimSpace(req.Avatar),
		OwnerID:     userID,
		// Owning tenant is pinned at create time; never changes even if
		// the owner user later moves to another tenant. See migration
		// 000046 and the isOwnerTenant helper below.
		OwnerTenantID:          tenantID,
		InviteCode:             generateInviteCode(),
		InviteCodeExpiresAt:    resolveInviteExpiry(validityDays, now),
		InviteCodeValidityDays: validityDays,

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Send a non-negative member_limit (or omit the field to use DefaultMemberLimit).
  2. Validate the value client-side before calling CreateOrganization.
  3. 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.

Example fix

// before
req := &types.CreateOrganizationRequest{Name: "acme", MemberLimit: &negLimit} // negLimit = -1
// after
limit := 100
if negLimit >= 0 { limit = negLimit }
req := &types.CreateOrganizationRequest{Name: "acme", MemberLimit: &limit}
Defensive patterns

Strategy: validation

Validate before calling

if req.MemberLimit != nil && *req.MemberLimit < 0 {
    return fmt.Errorf("member_limit must be >= 0, got %d", *req.MemberLimit)
}

Type guard

func validMemberLimit(p *int) bool { return p == nil || *p >= 0 }

Prevention

When it happens

Trigger: 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.

Common situations: Client forms allowing negative inputs, API clients sending 0-means-unlimited conventions from other systems as -1, or misconfigured default values in provisioning scripts.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/3b44ac8f340a888c. Report an issue: GitHub.