tursodatabase/turso · error · ProgrammingError
query timeout must be non-negative
Error message
query timeout must be non-negative
What it means
Connection.set_query_timeout(milliseconds) in pyturso sets a per-statement deadline enforced inside the engine, with 0 meaning 'disabled'. The Python wrapper checks the argument before it reaches the engine and raises ProgrammingError for any negative number. The negative value never reaches the Rust core; it is rejected at the API boundary.
Solutions
- Pass 0 to disable the timeout instead of a negative value
- Clamp computed deadlines before the call: set_query_timeout(max(0, remaining_ms))
- If you meant seconds, multiply by 1000 and pass a non-negative result
Example fix
// before conn.set_query_timeout(remaining_ms) // remaining_ms can be -500 after a slow retry // after conn.set_query_timeout(max(0, remaining_ms))
Defensive patterns
Strategy: validation
Validate before calling
def safe_set_query_timeout(conn, milliseconds: int) -> None:
if milliseconds < 0:
raise ValueError(f"timeout must be >= 0, got {milliseconds}")
conn.set_query_timeout(milliseconds) Try / catch
from turso.lib import ProgrammingError
try:
conn.set_query_timeout(ms)
except ProgrammingError:
conn.set_query_timeout(0) # fall back to 'disabled' Prevention
- Treat 0 as the only 'disabled' sentinel, never -1
- Compute deadlines with time.monotonic() so remaining time stays meaningful
- Validate duration inputs at your own API boundary before they reach the driver
When it happens
Trigger: Calling conn.set_query_timeout(-1) directly, or passing a computed value like (deadline_ms - now_ms) that has already gone negative because the deadline is in the past. Also passing seconds where milliseconds are expected makes surprising values but only negative ones raise.
Common situations: Deadline math based on wall-clock time that expires before the call; code ported from APIs where -1 means 'no timeout'; unit confusion between seconds and milliseconds.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Named parameters are not supported; use positional…
- size must be non-negative
- Cannot operate on a closed cursor
- executemany() requires a single DML…
- batch mode must be one of
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20).
Data as JSON: /api/errors/29822dbf469dbaaf.
Report an issue: GitHub.
Appendix: source
Thrown at bindings/python/turso/lib.py:556
``OperationalError`` ("interrupted"). The underlying execution methods
release the GIL, so a watchdog thread can actually run while a query is
busy. If no statement is running the call is a no-op.
"""
try:
self._conn.interrupt()
except Exception as exc: # noqa: BLE001
raise _map_turso_exception(exc)
def set_query_timeout(self, milliseconds: int) -> None:
"""
Set the maximum time (in milliseconds) a single statement may run before
it is interrupted (raising ``OperationalError``). ``0`` disables the
timeout. Unlike ``interrupt()`` this needs no watchdog thread: the
deadline is enforced inside the engine. Turso extension (not in stdlib
``sqlite3``).
"""
if milliseconds < 0:
raise ProgrammingError("query timeout must be non-negative")
try:
self._conn.set_query_timeout(milliseconds)
except Exception as exc: # noqa: BLE001
raise _map_turso_exception(exc)
def get_query_timeout(self) -> int:
"""Return the current per-statement query timeout in milliseconds (``0`` = disabled)."""
try:
return self._conn.get_query_timeout()
except Exception as exc: # noqa: BLE001
raise _map_turso_exception(exc)
def _maybe_implicit_begin(self, sql: str) -> None:
"""
Implement sqlite3 legacy implicit transaction behavior:
If autocommit is LEGACY_TRANSACTION_CONTROL, isolation_level is not None, sql is a DML
(INSERT/UPDATE/DELETE/REPLACE), and there is no open transaction, issue:View on GitHub (pinned to c1e5928725)