tursodatabase/turso · error · ProtocolError

pipeline response has {len(results)} results for {len(reqs)}

Error message

pipeline response has {len(results)} results for {len(reqs)} requests

What it means

ProtocolError raised by Session.execute_pipeline (session.py:243-246) when the results array length differs from the number of requests sent — the protocol (section 5.2) guarantees exactly one result per request, and a mismatch would silently misattribute results to the wrong requests, so the driver aborts instead of guessing. Note the baton/base_url were already applied from the response before this check.

Source

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

        """Execute a pipeline (section 5). When `track_autocommit` is set, a
        `get_autocommit` request is appended and its answer refreshes the
        cached transaction state; the returned results cover only the
        caller's requests."""
        reqs = list(requests)
        if track_autocommit:
            reqs.append({"type": "get_autocommit"})
        raw = self._post("/v3/pipeline", {"baton": self._baton, "requests": reqs})
        try:
            resp: dict[str, Any] = json.loads(raw)
        except ValueError as e:
            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

View on GitHub (pinned to bad083fafb)

Solutions

  1. Connect the client directly to the database endpoint and retry
  2. Align client and server versions
  3. Report with the captured response — the driver cannot safely recover a misaligned result set
Defensive patterns

Strategy: try-catch

Try / catch

from turso_serverless.protocol import ProtocolError

try:
    conn.executescript(script)
except ProtocolError as e:
    if "results for" not in str(e) or "requests" not in str(e):
        raise
    # misaligned results cannot be attributed safely: stop, reconnect, surface
    raise RuntimeError("pipeline result count mismatch — check proxies/server version") from e

Prevention

When it happens

Trigger: A response-mutating proxy drops or duplicates elements of the results array; a buggy server build returns results for a different request stream; version skew in pipeline semantics.

Common situations: Custom API gateways or caches in front of the database; preview/alternative server implementations that are not protocol-conformant.

Related errors


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