{"record":{"id":"1e780cd044b78a47","repo":"fullstackhero/dotnet-starter-kit","slug":"provisioning-not-found-for-tenant-tenantid","errorCode":null,"errorMessage":"Provisioning not found for tenant {tenantId}.","messagePattern":"Provisioning not found for tenant (.+?)\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Multitenancy/Modules.Multitenancy/Provisioning/TenantProvisioningService.cs","lineNumber":88,"sourceCode":"        await _dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);\n\n        return provisioning;\n    }\n\n    public async Task<TenantProvisioning?> GetLatestAsync(string tenantId, CancellationToken cancellationToken)\n    {\n        return await _dbContext.Set<TenantProvisioning>()\n            .Include(p => p.Steps)\n            .Where(p => p.TenantId == tenantId)\n            .OrderByDescending(p => p.CreatedUtc)\n            .FirstOrDefaultAsync(cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    public async Task<TenantProvisioningStatusDto> GetStatusAsync(string tenantId, CancellationToken cancellationToken)\n    {\n        var provisioning = await GetLatestAsync(tenantId, cancellationToken).ConfigureAwait(false)\n            ?? throw new NotFoundException($\"Provisioning not found for tenant {tenantId}.\");\n\n        return ToDto(provisioning);\n    }\n\n    public async Task EnsureCanActivateAsync(string tenantId, CancellationToken cancellationToken)\n    {\n        var provisioning = await GetLatestAsync(tenantId, cancellationToken).ConfigureAwait(false);\n        if (provisioning is null)\n        {\n            return;\n        }\n\n        if (provisioning.Status != TenantProvisioningStatus.Completed)\n        {\n            throw new CustomException($\"Tenant {tenantId} is not provisioned. Status: {provisioning.Status}.\");\n        }\n    }\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Multitenancy/Modules.Multitenancy/Provisioning/TenantProvisioningService.cs#L70-L106","documentation":"GetStatusAsync loads the most recent TenantProvisioning record for the tenant and throws NotFoundException when none exists. It means provisioning has never been started for this tenant, so there is no status to report. The exception maps to a 404-style response.","triggerScenarios":"Calling GetStatusAsync for a tenantId that never had StartAsync invoked; passing a misspelled or stale tenant id; querying status after the provisioning rows were purged; checking status on the wrong environment/database.","commonSituations":"Dashboard polling status immediately after tenant creation but before provisioning starts; typo'd tenant id in a script; pointing the API at a different database than where provisioning ran; data cleanup job removed old provisioning records.","solutions":["Start provisioning first (StartAsync) before querying status.","Verify the tenantId is correct and the tenant exists (Tenant {id} not found would otherwise surface).","Check the API/DbMigrator is connected to the correct database/environment where provisioning ran.","Handle the NotFound case in the client: treat it as 'never provisioned' and show a start-provisioning action instead of retrying."],"exampleFix":"// before\nvar status = await provisioningService.GetStatusAsync(tenantId, ct);\n\n// after\nvar tenant = await tenantService.GetAsync(tenantId, ct); // throws if tenant missing\nvar provisioning = await db.Set<TenantProvisioning>()\n    .FirstOrDefaultAsync(p => p.TenantId == tenantId, ct);\nif (provisioning is null)\n{\n    await provisioningService.StartAsync(tenantId, ct);\n    provisioning = await provisioningService.GetStatusAsync(tenantId, ct);\n}","handlingStrategy":"validation","validationCode":"var provisioningExists = await db.Set<TenantProvisioning>().AnyAsync(p => p.TenantId == tenantId, ct);\nif (!provisioningExists) await provisioningService.StartAsync(tenantId, ct);","typeGuard":"bool HasProvisioning(TenantProvisioningStatusDto? s) => s is not null;","tryCatchPattern":"try\n{\n    var status = await provisioningService.GetStatusAsync(tenantId, ct);\n}\ncatch (NotFoundException)\n{\n    // never provisioned — start it instead of polling forever\n    await provisioningService.StartAsync(tenantId, ct);\n}","preventionTips":["Kick off provisioning immediately after tenant creation so status always exists.","Validate tenant ids against the tenant list before querying status.","Confirm environment/database alignment between where you provision and where you query.","Handle the never-provisioned case explicitly in dashboards."],"tags":["multitenancy","provisioning","not-found"],"backgroundTag":"record-not-found","analyzedSha":"3f2959e683e9f83f13e55e1678c9119f63c7e8e5","analyzedAt":"2026-09-15T22:20:53.684Z","contentChangedAt":"2026-09-15T22:20:53.684Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}