{"record":{"id":"d64f17c41e409857","repo":"bitwarden/server","slug":"the-maximum-number-of-projects-for-this-plan-is","errorCode":null,"errorMessage":"The maximum number of projects for this plan is ({max}).","messagePattern":"The maximum number of projects for this plan is \\((.+?)\\)\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs","lineNumber":84,"sourceCode":"        }\n\n        if (importRequest.Projects?.Count() > 1000 || importRequest.Secrets?.Count() > 6000)\n        {\n            throw new BadRequestException(\"You cannot import this much data at once, the limit is 1000 projects and 6000 secrets.\");\n        }\n\n        if (importRequest.Secrets.Any(s => s.ProjectIds.Count() > 1))\n        {\n            throw new BadRequestException(\"A secret can only be in one project at a time.\");\n        }\n\n        var projectsToAdd = importRequest.Projects?.Count();\n        if (projectsToAdd is > 0)\n        {\n            var (max, overMax) = await _maxProjectsQuery.GetByOrgIdAsync(organizationId, projectsToAdd.Value);\n            if (overMax != null && overMax.Value)\n            {\n                throw new BadRequestException($\"The maximum number of projects for this plan is ({max}).\");\n            }\n        }\n\n        await _importCommand.ImportAsync(organizationId, importRequest.ToSMImport());\n    }\n}\n","sourceCodeStart":66,"sourceCodeEnd":91,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs#L66-L91","documentation":"Thrown at SecretsManagerPortingController.cs:84 inside Import. When projectsToAdd > 0, the IMaxProjectsQuery.GetByOrgIdAsync returns (max, overMax); if overMax is true the request would push the organization past its plan's project cap, so the controller throws BadRequestException($\"The maximum number of projects for this plan is ({max}).\") -> HTTP 400 with the numeric limit interpolated. This is a plan/entitlement business limit, not malformed input.","triggerScenarios":"POST /sm/{org}/import whose new project count, added to existing projects, exceeds the organization's current plan tier project maximum.","commonSituations":"Free/starter plan org trying to import a large project set; plan downgrade left the org at/over cap; bulk import after already using the quota.","solutions":["Upgrade the organization's plan to raise the project maximum, then re-import.","Delete or consolidate existing projects to free quota before importing.","Import only projects that fit under the remaining quota and defer the rest."],"exampleFix":"// before: import would exceed plan cap\nawait adminClient.PostAsync($\"/sm/{orgId}/import\", importJson); // 400: max is (N)\n\n// after: check remaining quota, then upgrade or trim\nvar remaining = await GetRemainingProjectQuotaAsync(orgId);\nif (import.Projects.Count() > remaining) {\n    await UpgradePlanAsync(orgId); // or trim the import set\n}\nawait adminClient.PostAsync($\"/sm/{orgId}/import\", importJson);","handlingStrategy":"validation","validationCode":"var (max, used) = await GetProjectQuotaAsync(orgId);\nif (used + import.Projects.Count() > max)\n    throw new InvalidOperationException($\"Would exceed plan cap of {max} projects\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check remaining project quota before importing.","Upgrade the plan or free quota by deleting unused projects.","Import only the projects that fit under the cap."],"tags":["csharp","aspnet","bitwarden","secrets-manager","import","plan-limit","billing","api"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}