{"record":{"id":"81924265abc5bb14","repo":"RayWangQvQ/BiliBiliToolPro","slug":"unable-to-get-sqliteconfigurationprovider","errorCode":null,"errorMessage":"Unable to get SqliteConfigurationProvider","messagePattern":"Unable to get SqliteConfigurationProvider","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Ray.BiliBiliTool.Web/Components/Pages/Configs/BaseConfigComponent.cs","lineNumber":81,"sourceCode":"            _isLoading = false;\n            StateHasChanged();\n        }\n\n        return Task.CompletedTask;\n    }\n\n    protected virtual async Task HandleValidSubmitAsync()\n    {\n        _isLoading = true;\n        _saveMessage = null;\n\n        try\n        {\n            // 保存配置\n            var sqliteProvider = GetSqliteConfigurationProvider();\n            if (sqliteProvider == null)\n            {\n                throw new InvalidOperationException(\"Unable to get SqliteConfigurationProvider\");\n            }\n\n            var configValues = _config.ToConfigDictionary();\n            sqliteProvider.BatchSet(configValues);\n\n            // 如果有对应的定时任务，同步更新 Quartz 任务状态和 Cron 表达式\n            var jobKey = GetJobKey();\n            if (jobKey != null && SchedulerService != null)\n            {\n                // 更新 Cron 表达式\n                await UpdateJobCronAsync(jobKey, _config.Cron);\n\n                // 控制任务启停\n                await ControlScheduledJobAsyc(jobKey, _config.IsEnable);\n            }\n\n            _saveMessage = GetSaveSuccessMessage();\n            _saveSuccess = true;","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/RayWangQvQ/BiliBiliToolPro/blob/c599b2c0da964e16ea8c454397aa07bb16212628/src/Ray.BiliBiliTool.Web/Components/Pages/Configs/BaseConfigComponent.cs#L63-L99","documentation":"HandleValidSubmitAsync in the Blazor config page saves settings through the SqliteConfigurationProvider obtained from the app's IConfigurationRoot. If the provider cannot be resolved (GetSqliteConfigurationProvider() returns null) it throws InvalidOperationException('Unable to get SqliteConfigurationProvider'), meaning the in-memory configuration does not contain the SQLite config source that must back persisted settings.","triggerScenarios":"The host was built without the SQLite configuration source being added (e.g. AddSqliteConfig not invoked or DB path misconfigured), the IConfigurationRoot has no provider whose type is SqliteConfigurationProvider, or the page is rendered in an environment (test host, alternate startup) that constructs configuration differently.","commonSituations":"Running the Web UI with a custom Program.cs that omits the SQLite config registration; DB file path unwritable so provider initialization silently failed; upgrading the app with a startup refactor that dropped the provider.","solutions":["Ensure startup adds the SQLite configuration source (the AddSqliteConfig/extension used by the default Program.cs) before the Blazor app runs.","Verify the SQLite database file path exists and the process has write permission to it.","Check GetSqliteConfigurationProvider(): iterate configurationRoot.Providers and confirm a SqliteConfigurationProvider is present; fix the detection logic if the type changed after a refactor.","Run with the stock Program.cs/host builder to confirm default behavior, then re-apply customizations."],"exampleFix":"// before\nvar sqliteProvider = GetSqliteConfigurationProvider();\nif (sqliteProvider == null)\n    throw new InvalidOperationException(\"Unable to get SqliteConfigurationProvider\");\n// after (log available providers to diagnose, fail with context)\nvar providers = ((IConfigurationRoot)Configuration).Providers.Select(p => p.GetType().Name);\nlogger.LogError(\"No SqliteConfigurationProvider. Loaded: {Providers}\", string.Join(\",\", providers));\nthrow new InvalidOperationException($\"Unable to get SqliteConfigurationProvider. Loaded: [{string.Join(\\\",\\\", providers)}]\");","handlingStrategy":"validation","validationCode":"var root = (IConfigurationRoot)Configuration;\nbool hasSqlite = root.Providers.Any(p => p is SqliteConfigurationProvider);\nif (!hasSqlite)\n    logger.LogError(\"SQLite配置源未注册，无法保存配置\");","typeGuard":null,"tryCatchPattern":"try { await HandleValidSubmitAsync(); }\ncatch (InvalidOperationException ex)\n{\n    message = $\"保存失败：{ex.Message}。请确认应用以默认启动方式运行（包含SQLite配置源）\";\n}","preventionTips":["Always start the Web app via the stock Program.cs that registers the SQLite source","Ensure the SQLite DB path is writable by the process","After startup refactors, verify Providers still include SqliteConfigurationProvider","Surface provider diagnostics in the config page on failure"],"tags":["blazor","configuration","sqlite","provider-missing"],"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"}