{"record":{"id":"243759f05b2aaf02","repo":"fullstackhero/dotnet-starter-kit","slug":"connectionstring-can-t-be-null","errorCode":null,"errorMessage":"ConnectionString can't be null.","messagePattern":"ConnectionString can't be null\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/BuildingBlocks/Shared/Multitenancy/AppTenantInfo.cs","lineNumber":84,"sourceCode":"        }\n\n        IsActive = true;\n    }\n\n    public void Deactivate()\n    {\n        if (Id == MultitenancyConstants.Root.Id)\n        {\n            throw new InvalidOperationException(\"Invalid Tenant\");\n        }\n\n        IsActive = false;\n    }\n\n    string? IAppTenantInfo.ConnectionString\n    {\n        get => ConnectionString;\n        set => ConnectionString = value ?? throw new InvalidOperationException(\"ConnectionString can't be null.\");\n    }\n}","sourceCodeStart":66,"sourceCodeEnd":86,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/BuildingBlocks/Shared/Multitenancy/AppTenantInfo.cs#L66-L86","documentation":"The explicit IAppTenantInfo.ConnectionString setter on AppTenantInfo accepts only non-null values; assigning null throws InvalidOperationException(\"ConnectionString can't be null.\"). Finbuckle uses this interface property when resolving a tenant's database connection string, so a null there would break tenant store initialization.","triggerScenarios":"Finbuckle's tenant store or mapping code assigning null to IAppTenantInfo.ConnectionString — typically a tenant entity whose ConnectionString is null while the resolver tries to set it, or code calling the setter with a null connection string.","commonSituations":"Tenants created without a connection string (falling back to the shared database) then passed through a resolver that writes the property; deserialization of tenant data with a missing ConnectionString field; migrations/seed copying tenants between stores with nulls.","solutions":["Set an explicit empty string instead of null if the tenant uses the shared database.","Check tenant.ConnectionString for null before assigning through IAppTenantInfo.ConnectionString.","Ensure seeded/created tenants have ConnectionString populated when per-tenant databases are required.","Fix the tenant store/resolver code so it only writes non-null connection strings."],"exampleFix":"// before\ntenantInfo.ConnectionString = maybeNullFromDb; // throws if null\n\n// after\nif (maybeNullFromDb is not null)\n    ((IAppTenantInfo)tenantInfo).ConnectionString = maybeNullFromDb;","handlingStrategy":"type-guard","validationCode":"if (tenant.ConnectionString is null)\n    throw new InvalidOperationException(\"Tenant connection string must be set before assignment.\");","typeGuard":"bool HasConnectionString(AppTenantInfo t) => !string.IsNullOrEmpty(t.ConnectionString);","tryCatchPattern":"try {\n    ((IAppTenantInfo)tenantInfo).ConnectionString = resolved;\n} catch (InvalidOperationException ex) when (ex.Message.Contains(\"ConnectionString\")) {\n    logger.LogError(\"Tenant {TenantId} has a null connection string\", tenantInfo.Id);\n}","preventionTips":["Treat ConnectionString as required for per-tenant-database tenants; use empty string for shared-database tenants.","Make seeding/migration code never write nulls into tenant store fields.","Add a startup check that logs tenants with null connection strings before Finbuckle resolves them."],"tags":["multitenancy","connection-string","finbuckle"],"backgroundTag":"null-argument","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"}