{"record":{"id":"7ae55a60ab428129","repo":"bitwarden/server","slug":"invalid-report-id","errorCode":null,"errorMessage":"Invalid report ID","messagePattern":"Invalid report ID","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Dirt/Controllers/OrganizationReportsController.cs","lineNumber":502,"sourceCode":"    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    {\n        EnsureValidIds(organizationId, reportId);\n\n        await AuthorizeAsync(organizationId);\n\n        var summaryData =\n            await _getOrganizationReportSummaryDataQuery.GetOrganizationReportSummaryDataAsync(organizationId, reportId);\n\n        if (summaryData == null)\n        {","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Dirt/Controllers/OrganizationReportsController.cs#L484-L520","documentation":"Thrown by GetAuthorizedReportAsync (the shared helper behind report-by-id endpoints) when the fetched report's OrganizationId does not equal the organizationId in the request path. The report exists but belongs to a different organization — a cross-org access attempt, surfaced as 400 'Invalid report ID' rather than 404.","triggerScenarios":"Client supplies a valid reportId that belongs to org A but pairs it with org B's organizationId in the URL. The report is loaded by reportId alone, then the org ownership is compared and mismatched.","commonSituations":"Copy-paste of a reportId across organizations; client mixed up ids from multiple orgs; URL built from two different sources; test fixture reused a reportId across orgs.","solutions":["Ensure the reportId and organizationId in the request come from the same report record.","Re-fetch the report list for the intended org to obtain the correct reportId.","Client-side, scope report ids per organization to avoid cross-contamination."],"exampleFix":"// before: reportId sourced from another org\nvar url = $\"/reports/organizations/{orgB}/{reportFromOrgA}\";\n// after\nvar report = await ListReportsAsync(orgB).First(r => /* match */);\nvar url = $\"/reports/organizations/{orgB}/{report.Id}\";","handlingStrategy":"validation","validationCode":"var report = await GetReportAsync(reportId);\nif (report.OrganizationId != organizationId)\n    throw new InvalidOperationException(\"Report does not belong to the specified organization.\");","typeGuard":null,"tryCatchPattern":"try { await client.GetAsync($\"/reports/organizations/{orgId}/{reportId}\"); }\ncatch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.BadRequest && ex.Message.Contains(\"Invalid report ID\"))\n{ /* reportId belongs to a different org — re-fetch the correct id */ }","preventionTips":["Always pair a reportId with the organizationId of the org that owns it.","Scope stored report ids per organization to avoid mix-ups.","On this 400, re-list reports for the intended org to get the right id."],"tags":["validation","authorization","cross-organization","identifiers","csharp","aspnetcore"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}