{"record":{"id":"48bb98d04d89061f","repo":"bitwarden/server","slug":"reportid-is-required","errorCode":null,"errorMessage":"ReportId is required.","messagePattern":"ReportId is required\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Dirt/Controllers/OrganizationReportsController.cs","lineNumber":493,"sourceCode":"        }\n\n        var orgAbility = await _organizationAbilityCacheService.GetOrganizationAbilityAsync(organizationId);\n        if (orgAbility is null || !orgAbility.UseRiskInsights)\n        {\n            throw new BadRequestException(\"Your organization's plan does not support this feature.\");\n        }\n    }\n\n    private static void EnsureValidIds(Guid organizationId, Guid? reportId = null)\n    {\n        if (organizationId == Guid.Empty)\n        {\n            throw new BadRequestException(\"OrganizationId is required.\");\n        }\n\n        if (reportId.HasValue && reportId.Value == Guid.Empty)\n        {\n            throw new BadRequestException(\"ReportId is required.\");\n        }\n    }\n\n    private async Task<OrganizationReport> GetAuthorizedReportAsync(Guid organizationId, Guid reportId)\n    {\n        EnsureValidIds(organizationId, reportId);\n        await AuthorizeAsync(organizationId);\n        var report = await _getOrganizationReportQuery.GetOrganizationReportAsync(reportId);\n        if (report.OrganizationId != organizationId) throw new BadRequestException(\"Invalid report ID\");\n        return report;\n    }\n\n\n    // Is being used by client on V2\n\n    [HttpGet(\"{organizationId}/data/summary/{reportId}\")]\n    public async Task<IActionResult> GetOrganizationReportSummaryAsync(Guid organizationId, Guid reportId)\n    {","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Dirt/Controllers/OrganizationReportsController.cs#L475-L511","documentation":"Thrown by EnsureValidIds when reportId is provided and equals Guid.Empty. Companion guard to error 317; runs on endpoints that accept a reportId in the path.","triggerScenarios":"Client sends an empty GUID for reportId; route template left the reportId segment as the default; client passed default(Guid) after a failed lookup.","commonSituations":"Client lost the report id between operations; URL builder used an uninitialized field; integration test forgot to capture the created report's id.","solutions":["Capture the reportId from the create-report response and pass it through.","Guard client-side: throw if reportId == Guid.Empty before the call.","If the id is unknown, list/get the report first to recover it."],"exampleFix":"// before\nvar url = $\"/reports/organizations/{orgId}/{reportId}\"; // reportId may be default\n// after\nif (reportId == Guid.Empty) throw new ArgumentException(\"reportId required\", nameof(reportId));\nvar url = $\"/reports/organizations/{orgId}/{reportId}\";","handlingStrategy":"validation","validationCode":"if (reportId == Guid.Empty)\n    throw new ArgumentException(\"reportId must be a non-empty GUID.\", nameof(reportId));","typeGuard":"static bool IsValidReportId(Guid id) => id != Guid.Empty;","tryCatchPattern":"try { await client.GetAsync($\"/reports/organizations/{orgId}/{reportId}\"); }\ncatch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.BadRequest && ex.Message.Contains(\"ReportId\"))\n{ /* recover the report id by listing reports, then retry */ }","preventionTips":["Capture reportId from create-report and thread it through.","Assert non-empty GUID before the call.","Recover lost ids via a report listing."],"tags":["validation","identifiers","request-shape","csharp","aspnetcore"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}