tursodatabase/turso · error · ProtocolError
invalid value in server response
Error message
invalid value in server response: {e} What it means
decode_value() converts one protocol value dict into a Python value. Missing keys ('type', 'value', 'base64'), wrong JSON shapes, or a float field that cannot be converted raise KeyError, TypeError, or ValueError inside the decoder; all three are re-raised as ProtocolError('invalid value in server response: ...') with the original cause discarded (from None). This error always means the server produced a value object that violates the protocol.
Solutions
- Upgrade the turso_serverless client to match the server version
- Confirm the URL points at a real Turso/Hrana endpoint rather than something that rewrites responses
- Capture the raw HTTP body of the failing response and report it to maintainers
Defensive patterns
Strategy: try-catch
Try / catch
from turso_serverless.protocol import ProtocolError
try:
rows = conn.execute(sql, params).fetchall()
except ProtocolError as e:
if "invalid value in server response" in str(e):
log.error("server sent a malformed value; client=%s", client_version)
raise
raise Prevention
- Keep client and server versions aligned; upgrade both together
- Log the failing statement and parameter types when decode errors appear
- Do not put transforming proxies between the client and the database endpoint
When it happens
Trigger: A server or intermediary returns a value without its 'type' or 'value' key; a float value containing a non-numeric string; a blob entry with malformed base64.
Common situations: Version skew between an upgraded server and an older client; a gateway or proxy mangling JSON bodies; a server bug emitting malformed rows for specific data.
Related errors
- batch response does not have one result and one error per…
- batch response is missing the result for statement
- expected batch result in pipeline response, got
- invalid rowid in server response
- unsupported value type in server response
AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20).
Data as JSON: /api/errors/64db8054b3f49d75.
Report an issue: GitHub.
Appendix: source
Thrown at serverless/python/turso_serverless/protocol.py:75
if typ == "null":
return None
if typ == "integer":
return int(pv["value"])
if typ == "float":
raw = pv["value"]
# A null value encodes a non-finite float (section 8.2); the
# spec says to decode it as NaN.
if raw is None:
return math.nan
return float(raw)
if typ == "text":
return pv["value"]
if typ == "blob":
# The server may omit base64 padding (section 8).
b64 = pv["base64"]
return base64.b64decode(b64 + "=" * (-len(b64) % 4))
except (KeyError, TypeError, ValueError) as e:
raise ProtocolError(f"invalid value in server response: {e}") from None
raise ProtocolError(f"unsupported value type in server response: {typ!r}")
def build_batch_step(
sql: str,
args: Optional[list] = None,
named_args: Optional[list[tuple[str, Any]]] = None,
want_rows: bool = True,
condition: Optional[dict] = None,
) -> dict:
"""Build a batch step for a cursor request (section 7)."""
encoded_args = [encode_value(a) for a in args] if args else []
encoded_named = (
[{"name": name, "value": encode_value(val)} for name, val in named_args]
if named_args
else []
)
step: dict = {View on GitHub (pinned to 244cde92a7)