tursodatabase/turso · error · ProtocolError

expected get_autocommit result in pipeline response, got {re

Error message

expected get_autocommit result in pipeline response, got {response}

What it means

ProtocolError raised by Session.execute_pipeline (session.py:251-257) when the trailing get_autocommit request — which the driver appends to every pipeline to track transaction state — comes back with the wrong result type or a non-bool is_autocommit field. The server answered, but the last result is not the probe the driver sent (section 5.2 ordering). The cached transaction state is left untouched.

Source

Thrown at serverless/python/turso_serverless/session.py:255

            self._reset_stream()
            raise ProtocolError(f"invalid pipeline response: {e}") from None
        self._update_stream(resp.get("baton"), resp.get("base_url"))
        results = resp.get("results") or []
        # The protocol guarantees one result per request (section 5.2); a
        # mismatch would misattribute results to the wrong requests.
        if len(results) != len(reqs):
            raise ProtocolError(
                f"pipeline response has {len(results)} results for {len(reqs)} requests"
            )
        if track_autocommit:
            result = results.pop()
            if result.get("type") == "error":
                raise _server_error(result.get("error"))
            response = result.get("response") or {}
            if response.get("type") != "get_autocommit" or not isinstance(
                response.get("is_autocommit"), bool
            ):
                raise ProtocolError(
                    f"expected get_autocommit result in pipeline response, got {response}"
                )
            self._autocommit = response["is_autocommit"]
        return results

    def _refresh_autocommit(self) -> None:
        """Refresh the cached transaction state with a standalone
        `get_autocommit` request. Failures are swallowed: this runs on error
        paths where the original failure must not be masked, and a dead
        stream already reset the state to autocommit."""
        try:
            self.execute_pipeline([], track_autocommit=True)
        except Exception:
            pass

    @staticmethod
    def _autocommit_probe_step() -> dict:
        """The trailing batch step appended to every cursor batch: a no-op

View on GitHub (pinned to bad083fafb)

Solutions

  1. Use a server release compatible with the driver's protocol version
  2. Remove intermediaries that reorder or filter pipeline requests/results
  3. Capture the response and report; the transaction-state tracking cannot work against a non-conformant peer
Defensive patterns

Strategy: try-catch

Try / catch

from turso_serverless.protocol import ProtocolError

try:
    conn.executescript(script)
except ProtocolError as e:
    if not str(e).startswith("expected get_autocommit result"):
        raise
    raise RuntimeError(
        "server broke pipeline ordering; verify client/server protocol versions"
    ) from e

Prevention

When it happens

Trigger: A proxy or server reorders/drops pipeline results so the last entry is not the get_autocommit answer; a server version that does not support get_autocommit returns an error or different shape in that slot.

Common situations: Version skew between the Python driver and an older/alternative server; gateways that filter request types or reorder array elements.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/73a2e8e9bd1a10d6. Report an issue: GitHub.