{"record":{"id":"64db8054b3f49d75","repo":"tursodatabase/turso","slug":"invalid-value-in-server-response-e","errorCode":null,"errorMessage":"invalid value in server response: {e}","messagePattern":"invalid value in server response: (.+?)","errorType":"exception","errorClass":"ProtocolError","httpStatus":null,"severity":"error","filePath":"serverless/python/turso_serverless/protocol.py","lineNumber":75,"sourceCode":"        if typ == \"null\":\n            return None\n        if typ == \"integer\":\n            return int(pv[\"value\"])\n        if typ == \"float\":\n            raw = pv[\"value\"]\n            # A null value encodes a non-finite float (section 8.2); the\n            # spec says to decode it as NaN.\n            if raw is None:\n                return math.nan\n            return float(raw)\n        if typ == \"text\":\n            return pv[\"value\"]\n        if typ == \"blob\":\n            # The server may omit base64 padding (section 8).\n            b64 = pv[\"base64\"]\n            return base64.b64decode(b64 + \"=\" * (-len(b64) % 4))\n    except (KeyError, TypeError, ValueError) as e:\n        raise ProtocolError(f\"invalid value in server response: {e}\") from None\n    raise ProtocolError(f\"unsupported value type in server response: {typ!r}\")\n\n\ndef build_batch_step(\n    sql: str,\n    args: Optional[list] = None,\n    named_args: Optional[list[tuple[str, Any]]] = None,\n    want_rows: bool = True,\n    condition: Optional[dict] = None,\n) -> dict:\n    \"\"\"Build a batch step for a cursor request (section 7).\"\"\"\n    encoded_args = [encode_value(a) for a in args] if args else []\n    encoded_named = (\n        [{\"name\": name, \"value\": encode_value(val)} for name, val in named_args]\n        if named_args\n        else []\n    )\n    step: dict = {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/serverless/python/turso_serverless/protocol.py#L57-L93","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from turso_serverless.protocol import ProtocolError\n\ntry:\n    rows = conn.execute(sql, params).fetchall()\nexcept ProtocolError as e:\n    if \"invalid value in server response\" in str(e):\n        log.error(\"server sent a malformed value; client=%s\", client_version)\n        raise\n    raise","preventionTips":["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"],"tags":["python","protocol","server-response","deserialization"],"backgroundTag":"protocol-decode-error","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}