RayWangQvQ/BiliBiliToolPro · critical · InvalidOperationException

SqliteConfigurationProvider not found

Error message

SqliteConfigurationProvider not found

What it means

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.

Solutions

  1. Register the SQLite configuration source at startup exactly as the stock Program.cs does (AddSqliteConfig with a writable DB path).
  2. Verify the SQLite file exists and the process can write to its directory (fix Docker volume permissions).
  3. Confirm GetSqliteProvider() still matches the provider type — update the check if SqliteConfigurationProvider was renamed or wrapped.
  4. For tests, build a ConfigurationRoot with the real SqliteConfigurationProvider (temp DB file) instead of in-memory only.

Example fix

// before (test host)
var config = new ConfigurationBuilder().AddInMemoryCollection().Build();
// after
var config = new ConfigurationBuilder()
    .AddSqlite("Data Source=/tmp/test.db") // ensures SqliteConfigurationProvider exists
    .Build();
Defensive patterns

Strategy: validation

Validate before calling

var root = (IConfigurationRoot)configuration;
if (!root.Providers.Any(p => p is SqliteConfigurationProvider))
    logger.LogError("SQLite配置源未注册,新增账号将无法持久化");

Try / catch

try { await workflow.AddAsync(cookieStr); }
catch (InvalidOperationException ex)
{
    logger.LogError(ex, "保存新账号失败:SQLite配置提供程序不可用");
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of RayWangQvQ/BiliBiliToolPro@c599b2c0da (2026-09-12). Data as JSON: /api/errors/7210b0a398706c38. Report an issue: GitHub.

Appendix: source

Thrown at src/Ray.BiliBiliTool.Web/Services/Pages/BiliAccount/BiliAccountPageWorkflow.cs:39

    {
        var cookieList = _configurationRoot.GetSection("BiliBiliCookies").Get<List<string>>() ?? [];
        var accounts = new List<BiliAccountDto>();

        for (int i = 0; i < cookieList.Count; i++)
        {
            var cookieStr = cookieList[i];
            var userId = ParseUserId(cookieStr);
            accounts.Add(new BiliAccountDto(i, userId, cookieStr));
        }

        return Task.FromResult(accounts);
    }

    public Task AddAsync(string cookieStr)
    {
        var provider =
            GetSqliteProvider()
            ?? throw new InvalidOperationException("SqliteConfigurationProvider not found");

        var currentCount =
            _configurationRoot.GetSection("BiliBiliCookies").Get<List<string>>()?.Count ?? 0;
        provider.Set($"BiliBiliCookies__{currentCount}", cookieStr);
        ReloadConfiguration();
        return Task.CompletedTask;
    }

    public Task UpdateAsync(int index, string cookieStr)
    {
        var provider =
            GetSqliteProvider()
            ?? throw new InvalidOperationException("SqliteConfigurationProvider not found");

        provider.Set($"BiliBiliCookies__{index}", cookieStr);
        ReloadConfiguration();
        return Task.CompletedTask;
    }

View on GitHub (pinned to c599b2c0da)