{"record":{"id":"7210b0a398706c38","repo":"RayWangQvQ/BiliBiliToolPro","slug":"sqliteconfigurationprovider-not-found","errorCode":null,"errorMessage":"SqliteConfigurationProvider not found","messagePattern":"SqliteConfigurationProvider not found","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Ray.BiliBiliTool.Web/Services/Pages/BiliAccount/BiliAccountPageWorkflow.cs","lineNumber":39,"sourceCode":"    {\n        var cookieList = _configurationRoot.GetSection(\"BiliBiliCookies\").Get<List<string>>() ?? [];\n        var accounts = new List<BiliAccountDto>();\n\n        for (int i = 0; i < cookieList.Count; i++)\n        {\n            var cookieStr = cookieList[i];\n            var userId = ParseUserId(cookieStr);\n            accounts.Add(new BiliAccountDto(i, userId, cookieStr));\n        }\n\n        return Task.FromResult(accounts);\n    }\n\n    public Task AddAsync(string cookieStr)\n    {\n        var provider =\n            GetSqliteProvider()\n            ?? throw new InvalidOperationException(\"SqliteConfigurationProvider not found\");\n\n        var currentCount =\n            _configurationRoot.GetSection(\"BiliBiliCookies\").Get<List<string>>()?.Count ?? 0;\n        provider.Set($\"BiliBiliCookies__{currentCount}\", cookieStr);\n        ReloadConfiguration();\n        return Task.CompletedTask;\n    }\n\n    public Task UpdateAsync(int index, string cookieStr)\n    {\n        var provider =\n            GetSqliteProvider()\n            ?? throw new InvalidOperationException(\"SqliteConfigurationProvider not found\");\n\n        provider.Set($\"BiliBiliCookies__{index}\", cookieStr);\n        ReloadConfiguration();\n        return Task.CompletedTask;\n    }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/RayWangQvQ/BiliBiliToolPro/blob/c599b2c0da964e16ea8c454397aa07bb16212628/src/Ray.BiliBiliTool.Web/Services/Pages/BiliAccount/BiliAccountPageWorkflow.cs#L21-L57","documentation":"AddAsync persists a newly logged-in Bilibili cookie by writing key 'BiliBiliCookies__{n}' through the SQLite configuration provider. If GetSqliteProvider() returns null it throws InvalidOperationException('SqliteConfigurationProvider not found'), i.e. the configuration root doesn't contain the SQLite source required for persistence. Typically raised right after QR login (QrLoginCompleteAsync) when the app wasn't started with the SQLite config source.","triggerScenarios":"Host built without the SQLite configuration source registered, SQLite DB initialization failed (missing file/unwritable path), or the provider-detection helper (GetSqliteProvider) fails to match the provider type after a refactor, or running in a test host with in-memory configuration only.","commonSituations":"Custom Program.cs omitting AddSqliteConfig; read-only volume mounted at the DB path in Docker; tests exercising the account workflow with a fake configuration root lacking the SQLite provider.","solutions":["Register the SQLite configuration source at startup exactly as the stock Program.cs does (AddSqliteConfig with a writable DB path).","Verify the SQLite file exists and the process can write to its directory (fix Docker volume permissions).","Confirm GetSqliteProvider() still matches the provider type — update the check if SqliteConfigurationProvider was renamed or wrapped.","For tests, build a ConfigurationRoot with the real SqliteConfigurationProvider (temp DB file) instead of in-memory only."],"exampleFix":"// before (test host)\nvar config = new ConfigurationBuilder().AddInMemoryCollection().Build();\n// after\nvar config = new ConfigurationBuilder()\n    .AddSqlite(\"Data Source=/tmp/test.db\") // ensures SqliteConfigurationProvider exists\n    .Build();","handlingStrategy":"validation","validationCode":"var root = (IConfigurationRoot)configuration;\nif (!root.Providers.Any(p => p is SqliteConfigurationProvider))\n    logger.LogError(\"SQLite配置源未注册，新增账号将无法持久化\");","typeGuard":null,"tryCatchPattern":"try { await workflow.AddAsync(cookieStr); }\ncatch (InvalidOperationException ex)\n{\n    logger.LogError(ex, \"保存新账号失败：SQLite配置提供程序不可用\");\n}","preventionTips":["Register the SQLite config source at startup (AddSqliteConfig)","Ensure the SQLite DB file path is writable (check Docker volume permissions)","Keep GetSqliteProvider() in sync with the actual provider type after refactors","Verify persistence works after QR login in a fresh deployment"],"tags":["configuration","sqlite","provider-missing","persistence"],"backgroundTag":"missing-config-key","analyzedSha":"c599b2c0da964e16ea8c454397aa07bb16212628","analyzedAt":"2026-09-12T09:48:04.090Z","contentChangedAt":"2026-09-12T09:48:04.090Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}