tursodatabase/turso · error · ProtocolError
batch response does not have one result and one error per st
Error message
batch response does not have one result and one error per step: {result} What it means
When decoding a batch response from the server, the SDK expects the response to carry step_results and step_errors arrays with exactly one entry per submitted statement. If either array is missing, not a list, or has a different length than the number of steps, _decode_batch_result raises ProtocolError — the server response violates the expected protocol (section 8.4) and cannot be trusted.
Source
Thrown at serverless/python/turso_serverless/connection.py:379
result: dict,
stmts: list[tuple[str, Any]],
offset: int,
commit_index: int | None,
total_steps: int,
) -> list[BatchResult]:
"""Decode a wire-level batch result into per-statement results, or
raise the error of the step that failed. Failures of the synthetic
BEGIN/COMMIT steps surface as-is. A ROLLBACK failure is attached to
that primary error as `rollback_error`."""
step_results = result.get("step_results")
step_errors = result.get("step_errors")
if (
not isinstance(step_results, list)
or not isinstance(step_errors, list)
or len(step_results) != total_steps
or len(step_errors) != total_steps
):
raise ProtocolError(
f"batch response does not have one result and one error per step: {result}"
)
# Decode the results of the statements that executed before looking
# at the errors, so a failure can still report what completed.
results: list[BatchResult | None] = [
Connection._decode_batch_statement_result(step_results[offset + i], sql)
for i, (sql, _parameters) in enumerate(stmts)
]
rollback_error = None
if commit_index is not None and step_errors[commit_index + 1] is not None:
rollback_error = _classify_error(_server_error(step_errors[commit_index + 1]))
try:
Connection._raise_batch_step_error(step_errors, len(stmts), offset, commit_index, results)
except Exception as primary_error:
if rollback_error is not None:
primary_error.rollback_error = rollback_error
raise
if rollback_error is not None:View on GitHub (pinned to c1e5928725)
Solutions
- Upgrade the turso_serverless SDK and server together so protocol versions match.
- Print the full response object in the message and check whether step_results/step_errors exist at all (indicates talking to the wrong endpoint/server).
- Retry the batch — if a proxy corrupted the response, a fresh request may succeed.
- Reduce batch size to rule out size-related server truncation.
- Report to Turso support with the raw response if a current SDK against a current server still produces it.
Example fix
# before
results = conn.batch(stmts) # ProtocolError on shape mismatch
# after
try:
results = conn.batch(stmts)
except ProtocolError as e:
logger.error("malformed batch response: %s", e)
results = retry_batch(stmts) # or surface a clear client/server version mismatch Defensive patterns
Strategy: retry
Validate before calling
def batch_response_well_formed(result: dict, total_steps: int) -> bool:
sr, se = result.get("step_results"), result.get("step_errors")
return (
isinstance(sr, list) and isinstance(se, list)
and len(sr) == total_steps and len(se) == total_steps
) Try / catch
try:
results = conn.batch(stmts)
except ProtocolError as e:
log.error("malformed batch response: %s", e)
results = conn.batch(stmts) # retry once; persistent failure => version mismatch Prevention
- Keep SDK and server versions aligned.
- Avoid proxies that rewrite JSON bodies.
- Make batched statements idempotent so retries are safe.
- Report persistent shape violations to Turso with the raw response.
When it happens
Trigger: A server (or proxy) returns a batch reply whose step_results/step_errors are absent, truncated, or longer than the submitted steps — e.g. after a server upgrade, a gateway mangling the JSON, or a genuine server bug.
Common situations: Version mismatch between client SDK and server pipeline protocol, responses through caching/transforming proxies, hitting a non-Turso endpoint that echoes unexpected JSON, or server-side truncation on very large batches.
Related errors
- batch response is missing the result for statement {i}
- invalid rowid in server response: {e}
- expected batch result in pipeline response, got {response}
- invalid value in server response: {e}
- unsupported value type in server response: {typ!r}
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-31).
Data as JSON: /api/errors/10543fa2b2586e9f.
Report an issue: GitHub.