github/copilot-sdk · error · SessionFsSqliteTransactionFailure

SQLite transactions are not supported by this SessionFs…

Error message

SQLite transactions are not supported by this SessionFs provider

What it means

The base SessionFsSqliteProvider.sqlite_transaction method raises this SessionFsSqliteTransactionFailure (FATAL class) by default. It signals that the installed SessionFs provider implements sqlite_query/sqlite_exists but does not override sqlite_transaction, so atomic multi-statement execution is not available.

Solutions

  1. Implement sqlite_transaction in your provider (subclass SessionFsSqliteProvider and override it), running the statements atomically and returning one result per statement.
  2. If atomicity is not needed, override sqlite_transaction to run each statement via sqlite_query in order and return the results (accepting loss of atomicity).
  3. If your provider genuinely has no SQLite database, ensure sqlite_exists returns False so the runtime does not dispatch transaction calls, and avoid tools that require SQLite.
  4. Check that the provider instance actually inherits both SessionFsProvider and SessionFsSqliteProvider so the isinstance dispatch routes calls correctly.

Example fix

// before
class MyProvider(SessionFsProvider, SessionFsSqliteProvider):
    async def sqlite_query(self, query_type, query, params=None): ...
    # sqlite_transaction not overridden -> FATAL failure
// after
class MyProvider(SessionFsProvider, SessionFsSqliteProvider):
    async def sqlite_query(self, query_type, query, params=None): ...
    async def sqlite_transaction(self, statements):
        results = []
        for stmt in statements:
            r = await self.sqlite_query(stmt.query_type, stmt.query, stmt.params)
            results.append(r)
        return results
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(provider, SessionFsSqliteProvider):
    raise RuntimeError('provider does not support SQLite operations')
# also check provider overrides the transaction method:
if type(provider).sqlite_transaction is SessionFsSqliteProvider.sqlite_transaction:
    raise RuntimeError('provider does not implement sqlite_transaction')

Type guard

def supports_sqlite_transactions(provider) -> bool:
    return (
        isinstance(provider, SessionFsSqliteProvider)
        and type(provider).sqlite_transaction is not SessionFsSqliteProvider.sqlite_transaction
    )

Try / catch

try:
    results = await provider.sqlite_transaction(statements)
except SessionFsSqliteTransactionFailure as exc:
    if exc.error_class == SessionFSSqliteTransactionErrorClass.FATAL:
        raise  # transactions unsupported here; do not retry
    # busy_or_locked is safe to retry; post_commit_ambiguous never retry

Prevention

When it happens

Trigger: The runtime issues a SessionFS SQLite transaction request against a provider that subclasses SessionFsProvider + SessionFsSqliteProvider but relies on the default (non-overridden) sqlite_transaction implementation, or dispatches a transaction against a plain SessionFsProvider lacking SQLite support.

Common situations: Custom file-system provider author forgot to implement sqlite_transaction after implementing sqlite_query; upgrading the SDK adds transaction support to the runtime while a user's older custom provider predates it; accidentally registering a minimal provider where the app's tools use multi-statement SQLite workflows.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/445504d9a643fe77. Report an issue: GitHub.

Appendix: source

Thrown at python/copilot/session_fs_provider.py:152

    ) -> SessionFsSqliteQueryResult | None:
        """Execute a SQLite query against the provider's per-session database.

        Return ``None`` for exec-type queries (DDL / multi-statement) where
        no result set is produced; the adapter will substitute an empty result.
        """

    async def sqlite_transaction(
        self,
        statements: list[SessionFSSqliteTransactionStatement],
    ) -> list[SessionFsSqliteQueryResult]:
        """Execute ``statements`` atomically against the per-session database.

        Return one result per statement, in order.  Raise
        :class:`SessionFsSqliteTransactionFailure` to tell the runtime how the
        failure should be classified; any other exception is reported as
        ``fatal``.
        """
        raise SessionFsSqliteTransactionFailure(
            "SQLite transactions are not supported by this SessionFs provider",
            SessionFSSqliteTransactionErrorClass.FATAL,
        )

    @abc.abstractmethod
    async def sqlite_exists(self) -> bool:
        """Return whether the provider has a SQLite database for this session."""


class SessionFsSqliteTransactionFailure(Exception):
    """Raised by a provider to classify a failed SQLite transaction.

    ``busy_or_locked`` guarantees the transaction rolled back and is safe to
    retry; ``post_commit_ambiguous`` must never be retried.
    """

    def __init__(
        self,

View on GitHub (pinned to cd8cf15dc3)