{"record":{"id":"7ddfdd35681199da","repo":"fullstackhero/dotnet-starter-kit","slug":"tenant-tenantid-not-found-for-provisioning","errorCode":null,"errorMessage":"Tenant {tenantId} not found for provisioning.","messagePattern":"Tenant (.+?) not found for provisioning\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"src/Modules/Multitenancy/Modules.Multitenancy/Provisioning/TenantProvisioningService.cs","lineNumber":39,"sourceCode":"\n    public TenantProvisioningService(\n        TenantDbContext dbContext,\n        IMultiTenantStore<AppTenantInfo> tenantStore,\n        IJobService jobService,\n        IServiceScopeFactory scopeFactory,\n        ILogger<TenantProvisioningService> logger)\n    {\n        _dbContext = dbContext;\n        _tenantStore = tenantStore;\n        _jobService = jobService;\n        _scopeFactory = scopeFactory;\n        _logger = logger;\n    }\n\n    public async Task<TenantProvisioning> StartAsync(string tenantId, CancellationToken cancellationToken)\n    {\n        var tenant = await _tenantStore.GetAsync(tenantId).ConfigureAwait(false)\n            ?? throw new NotFoundException($\"Tenant {tenantId} not found for provisioning.\");\n\n        var existing = await GetLatestAsync(tenantId, cancellationToken).ConfigureAwait(false);\n        if (existing is not null && (existing.Status is TenantProvisioningStatus.Running or TenantProvisioningStatus.Pending))\n        {\n            throw new CustomException($\"Provisioning already running for tenant {tenantId}.\");\n        }\n\n        var correlationId = Guid.NewGuid().ToString();\n        var provisioning = new TenantProvisioning(tenant.Id, correlationId);\n\n        provisioning.Steps.Add(new TenantProvisioningStep(provisioning.Id, TenantProvisioningStepName.Database));\n        provisioning.Steps.Add(new TenantProvisioningStep(provisioning.Id, TenantProvisioningStepName.Migrations));\n        provisioning.Steps.Add(new TenantProvisioningStep(provisioning.Id, TenantProvisioningStepName.Seeding));\n        provisioning.Steps.Add(new TenantProvisioningStep(provisioning.Id, TenantProvisioningStepName.CacheWarm));\n\n        _dbContext.Add(provisioning);\n        await _dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Multitenancy/Modules.Multitenancy/Provisioning/TenantProvisioningService.cs#L21-L57","documentation":"TenantProvisioningService.StartAsync throws NotFoundException (\"Tenant {tenantId} not found for provisioning.\") when asked to start a provisioning run for a tenant id that does not exist in the tenant store. This is the synchronous entry point before a run row is created; the job-side equivalent is TenantProvisioningJob.RunAsync. A subsequent guard also rejects starts while a run is already Pending/Running.","triggerScenarios":"Calling the provisioning start API/endpoint with an unknown or deleted tenantId; a client racing tenant deletion with a provisioning request; a typo'd or truncated tenant id in the request.","commonSituations":"Admin UI caching a tenant list while the tenant was deleted elsewhere; retrying a failed request after the tenant was removed; integration tests hitting a cleaned database.","solutions":["Confirm the tenantId exists (GET the tenant) before starting provisioning.","Recreate the tenant if it was deleted and provisioning is needed.","Refresh the admin UI's tenant list to drop stale entries.","Fix the request payload if the id was mistyped or truncated."],"exampleFix":"// before\nawait provisioningService.StartAsync(\"acme-mispelled\", ct);\n// after\nvar tenant = await tenantStore.GetAsync(\"acme\", ct) ?? throw new NotFoundException(\"Tenant acme missing\");\nawait provisioningService.StartAsync(tenant.Id, ct);","handlingStrategy":"validation","validationCode":"var tenant = await tenantStore.GetAsync(tenantId, ct);\nif (tenant is null) return Result.NotFound($\"Tenant {tenantId} does not exist.\");","typeGuard":null,"tryCatchPattern":"try { await provisioningService.StartAsync(tenantId, ct); }\ncatch (NotFoundException) { refreshTenantList(); showError(\"Tenant not found — it may have been deleted.\"); }","preventionTips":["Fetch tenant ids from a live lookup, not cached lists.","Disable provisioning actions for tenants pending deletion.","Validate tenantId format/existence in the endpoint validator.","Refresh tenant pickers after any tenant lifecycle operation."],"tags":["multitenancy","provisioning","not-found","api"],"backgroundTag":"entity-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"}