tursodatabase/turso · error · ValueError
infinite float values cannot be sent over the protocol
Error message
infinite float values cannot be sent over the protocol
What it means
ValueError raised by encode_value() (protocol.py:38-44) when a bound parameter is a float equal to +inf or -inf. The SQL-over-HTTP protocol (section 8.2) has no encoding for infinities: JSON cannot carry them (the session even serializes with allow_nan=False), and unlike NaN — which becomes NULL because SQLite itself binds NaN as NULL — infinity is a meaningful REAL value that must not be silently rewritten, so the client refuses to send it.
Source
Thrown at serverless/python/turso_serverless/protocol.py:44
class ProtocolError(RuntimeError):
"""A transport failure or a response that violates the protocol."""
def encode_value(value: Any) -> dict:
"""Encode a Python value to a protocol value (section 8)."""
if value is None:
return {"type": "null"}
if isinstance(value, bool):
return {"type": "integer", "value": str(int(value))}
if isinstance(value, int):
return {"type": "integer", "value": str(value)}
if isinstance(value, float):
# The protocol forbids sending non-finite floats (section 8.2).
if math.isnan(value):
# SQLite binds NaN as NULL; JSON cannot carry it.
return {"type": "null"}
if math.isinf(value):
raise ValueError("infinite float values cannot be sent over the protocol")
return {"type": "float", "value": value}
if isinstance(value, str):
return {"type": "text", "value": value}
if isinstance(value, (bytes, bytearray)):
return {"type": "blob", "base64": base64.b64encode(value).decode("ascii")}
raise TypeError(f"Unsupported value type: {type(value).__name__}")
def decode_value(pv: dict) -> Any:
"""Decode a protocol value (section 8) to a Python value."""
try:
typ = pv["type"]
if typ == "null":
return None
if typ == "integer":
return int(pv["value"])
if typ == "float":
raw = pv["value"]View on GitHub (pinned to bad083fafb)
Solutions
- Check math.isinf(value) before binding and substitute NULL (if the column semantics allow) or reject the row
- Fix the upstream math: guard divide-by-zero and overflow before values reach the driver
- When ingesting JSON, parse with json.loads(..., parse_constant=lambda c: None) to map Infinity/NaN at the boundary
Example fix
// before
cur.execute("INSERT INTO metrics(v) VALUES (?)", (float('inf'),))
// after
v = float('inf')
cur.execute("INSERT INTO metrics(v) VALUES (?)", (None if math.isinf(v) else v,)) Defensive patterns
Strategy: validation
Validate before calling
import math
def sanitize_params(params):
"""The protocol cannot carry infinities; NaN is fine (binds as NULL)."""
out = []
for p in params:
if isinstance(p, float) and math.isinf(p):
raise ValueError("infinite float is not representable over the protocol")
out.append(p)
return out
cur.execute(sql, sanitize_params(params)) Type guard
import math
def is_bindable_number(v) -> bool:
"""True when encode_value will accept the float: finite, or NaN (-> NULL)."""
return not isinstance(v, float) or math.isfinite(v) or math.isnan(v) Try / catch
import math
try:
cur.execute(sql, params)
except ValueError as e:
if "infinite float" not in str(e):
raise
params = tuple(None if isinstance(p, float) and math.isinf(p) else p for p in params)
cur.execute(sql, params) Prevention
- Validate numeric columns with math.isfinite before insert when data comes from external sources
- Parse inbound JSON with json.loads(..., parse_constant=...) to reject or map Infinity at the boundary
- Guard division and exponentiation that can overflow to inf upstream of the driver
When it happens
Trigger: Binding math.inf / float('inf') / numpy.inf as a positional or named parameter; computed values that overflow (1e308 * 10); data loaded with Python's json module, which by default accepts the non-standard Infinity token and yields inf.
Common situations: ETL pipelines ingesting JSON logs containing Infinity; metrics code dividing without a zero guard and storing the result; pandas/numpy workflows converting np.inf to Python float before insert.
Related errors
- Unsupported value type: {type(value).__name__}
- invalid value in server response: {e}
- cursor response body ended before the cursor response line
- invalid cursor response: {e}
- invalid cursor entry: {e}
AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16).
Data as JSON: /api/errors/ee928da03a2483b8.
Report an issue: GitHub.