{"record":{"id":"6751624d6e97970d","repo":"tursodatabase/turso","slug":"transaction-must-be-a-sqlitetransaction","errorCode":null,"errorMessage":"Transaction must be a SqliteTransaction.","messagePattern":"Transaction must be a SqliteTransaction\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs","lineNumber":52,"sourceCode":"    }\n\n    public SqliteCommand(string? commandText, SqliteConnection? connection)\n        : this(commandText)\n    {\n        Connection = connection;\n    }\n\n    public SqliteCommand(string? commandText, SqliteConnection? connection, SqliteTransaction? transaction)\n        : this(commandText, connection)\n    {\n        Transaction = transaction;\n    }\n\n    public SqliteCommand(string? commandText, SqliteConnection? connection, DbTransaction? transaction)\n        : this(commandText, connection)\n    {\n        Transaction = transaction as SqliteTransaction\n                      ?? (transaction is null ? null : throw new ArgumentException(\"Transaction must be a SqliteTransaction.\", nameof(transaction)));\n    }\n\n    [AllowNull]\n    public override string CommandText\n    {\n        get => _commandText;\n        set\n        {\n            ThrowIfReaderOpen(nameof(CommandText));\n            _commandText = value ?? string.Empty;\n        }\n    }\n\n    public override int CommandTimeout\n    {\n        get => _commandTimeout;\n        set\n        {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/tursodatabase/turso/blob/6c7252267988c76e632af00a671e4b9788dfae13/bindings/dotnet/src/Turso.Data.Sqlite/SqliteCommand.cs#L34-L70","documentation":"SqliteCommand implements DbCommand, whose constructor accepts any DbTransaction; the provider understands only SqliteTransaction (its own type that talks to the native engine), so a non-null transaction of another ADO.NET provider is rejected with ArgumentException. Null is allowed and means 'not enlisted'. The check happens at construction so the failure surfaces before execution inside native code.","triggerScenarios":"new SqliteCommand(sql, conn, tx) where tx came from another provider (e.g., SqlTransaction) or from a different connection; generic ADO.NET helpers that thread DbTransaction through to any command; DI wiring that injects the wrong DbTransaction.","commonSituations":"Multi-database unit-of-work code passing one provider's transaction to another's command; copy-paste from System.Data.SqlClient samples; provider-agnostic data layers that lost type pairing.","solutions":["Pass the SqliteTransaction returned by sqliteConn.BeginTransaction().","Pattern-match before passing: only forward transactions that are SqliteTransaction.","In generic helpers, keep connection+transaction provider pairs together (DbProviderFactory) so the right types flow."],"exampleFix":"// before\nDbTransaction tx = GetUnitOfWorkTransaction();   // e.g. a SqlTransaction from SQL Server\nusing var cmd = new SqliteCommand(sql, conn, tx); // throws: must be a SqliteTransaction\n\n// after\nusing var tx = conn.BeginTransaction();           // SqliteTransaction from the same connection\nusing var cmd = new SqliteCommand(sql, conn, tx);","handlingStrategy":"type-guard","validationCode":"if (transaction is not null and not SqliteTransaction)\n    throw new ArgumentException(\"Transaction must come from a SqliteConnection.\");\n\nvar cmd = new SqliteCommand(sql, conn, transaction as SqliteTransaction);","typeGuard":"static SqliteTransaction? AsSqlite(DbTransaction? tx) => tx switch {\n    null => null,\n    SqliteTransaction s => s,\n    _ => throw new ArgumentException(\"Transaction must be a SqliteTransaction.\")\n};","tryCatchPattern":null,"preventionTips":["Begin transactions from the same SqliteConnection the command uses.","In generic code, keep provider pairs (connection+transaction) together via DbProviderFactory.","Never pass one provider's transaction into another provider's command."],"tags":["dotnet","ado-net","transaction","type-mismatch"],"backgroundTag":"invalid-transaction-type","analyzedSha":"6c7252267988c76e632af00a671e4b9788dfae13","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}