{"record":{"id":"73a2e8e9bd1a10d6","repo":"tursodatabase/turso","slug":"expected-get-autocommit-result-in-pipeline-respons","errorCode":null,"errorMessage":"expected get_autocommit result in pipeline response, got {response}","messagePattern":"expected get_autocommit result in pipeline response, got (.+?)","errorType":"exception","errorClass":"ProtocolError","httpStatus":null,"severity":"error","filePath":"serverless/python/turso_serverless/session.py","lineNumber":255,"sourceCode":"            self._reset_stream()\n            raise ProtocolError(f\"invalid pipeline response: {e}\") from None\n        self._update_stream(resp.get(\"baton\"), resp.get(\"base_url\"))\n        results = resp.get(\"results\") or []\n        # The protocol guarantees one result per request (section 5.2); a\n        # mismatch would misattribute results to the wrong requests.\n        if len(results) != len(reqs):\n            raise ProtocolError(\n                f\"pipeline response has {len(results)} results for {len(reqs)} requests\"\n            )\n        if track_autocommit:\n            result = results.pop()\n            if result.get(\"type\") == \"error\":\n                raise _server_error(result.get(\"error\"))\n            response = result.get(\"response\") or {}\n            if response.get(\"type\") != \"get_autocommit\" or not isinstance(\n                response.get(\"is_autocommit\"), bool\n            ):\n                raise ProtocolError(\n                    f\"expected get_autocommit result in pipeline response, got {response}\"\n                )\n            self._autocommit = response[\"is_autocommit\"]\n        return results\n\n    def _refresh_autocommit(self) -> None:\n        \"\"\"Refresh the cached transaction state with a standalone\n        `get_autocommit` request. Failures are swallowed: this runs on error\n        paths where the original failure must not be masked, and a dead\n        stream already reset the state to autocommit.\"\"\"\n        try:\n            self.execute_pipeline([], track_autocommit=True)\n        except Exception:\n            pass\n\n    @staticmethod\n    def _autocommit_probe_step() -> dict:\n        \"\"\"The trailing batch step appended to every cursor batch: a no-op","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/serverless/python/turso_serverless/session.py#L237-L273","documentation":"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.","triggerScenarios":"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.","commonSituations":"Version skew between the Python driver and an older/alternative server; gateways that filter request types or reorder array elements.","solutions":["Use a server release compatible with the driver's protocol version","Remove intermediaries that reorder or filter pipeline requests/results","Capture the response and report; the transaction-state tracking cannot work against a non-conformant peer"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from turso_serverless.protocol import ProtocolError\n\ntry:\n    conn.executescript(script)\nexcept ProtocolError as e:\n    if not str(e).startswith(\"expected get_autocommit result\"):\n        raise\n    raise RuntimeError(\n        \"server broke pipeline ordering; verify client/server protocol versions\"\n    ) from e","preventionTips":["Upgrade driver and server together — get_autocommit tracking depends on section 5.2 ordering","Do not filter or reorder pipeline requests/results in intermediary layers","Report reproducible occurrences with the raw response"],"tags":["python","protocol","pipeline","autocommit","response-parsing"],"backgroundTag":"malformed-server-response","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}