tursodatabase/turso · error · ProtocolError

unsupported value type in server response: {typ!r}

Error message

unsupported value type in server response: {typ!r}

What it means

decode_value() dispatches on the value's 'type' string and understands exactly five kinds: null, integer, float, text, and blob. A well-formed dict whose type is anything else falls past the if-chain to ProtocolError('unsupported value type in server response: ...'). Unlike the malformed-value error, this one means the JSON parsed fine but the client does not know this value type.

Source

Thrown at serverless/python/turso_serverless/protocol.py:76

            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 = {
        "stmt": {

View on GitHub (pinned to 244cde92a7)

Solutions

  1. Upgrade the turso_serverless client so it knows the new value type
  2. Pin client and server to a version pair you have tested together
  3. If you control the server, restrict stored values to the five core types
Defensive patterns

Strategy: try-catch

Try / catch

from turso_serverless.protocol import ProtocolError

try:
    value = conn.execute(sql).fetchone()
except ProtocolError as e:
    if "unsupported value type in server response" in str(e):
        log.error("client too old for this server's value types; upgrade turso_serverless")
        raise
    raise

Prevention

When it happens

Trigger: A newer server adds a value kind (for example a JSON type) that this client version does not know; an alternative server implementation extending the protocol with extra types.

Common situations: Server upgraded ahead of the client; canary deployments with mixed versions; third-party Hrana-compatible servers using extensions.

Related errors


AI-assisted analysis of tursodatabase/turso@244cde92a7 (2026-08-20). Data as JSON: /api/errors/b0d43b26399f93aa. Report an issue: GitHub.