tursodatabase/turso · error · ValueError
measurements must be finite and positive
Error message
measurements must be finite and positive
What it means
positive_number() is the final gate for every numeric field and computed measurement: values must be finite (not NaN/inf) and strictly positive. Non-numeric or non-positive measurements indicate a broken run and are rejected so plots never contain garbage points.
Solutions
- Fix the offending numeric value in the CSV so it is finite and > 0
- Re-run the benchmark to regenerate valid measurements
- Validate upstream collector output before writing the CSV
Example fix
// before (CSV) ...,seconds=0,... // after ...,seconds=12.5,...
Defensive patterns
Strategy: validation
Validate before calling
import math
def validate_positive(value):
v = float(value)
if not math.isfinite(v) or v <= 0:
raise ValueError("measurements must be finite and positive")
return v Type guard
def is_positive_finite(value) -> bool:
try:
v = float(value)
except (TypeError, ValueError):
return False
return math.isfinite(v) and v > 0 Try / catch
try:
configuration, runs = read_runs(path, percentile)
except ValueError as e:
print(f"bad measurement: {e}") Prevention
- Reject 0/negative/NaN placeholders at collection time
- Validate CSV numerics before plotting
- Check harness output for truncation or corruption that yields invalid numbers
When it happens
Trigger: A numeric column contains 0, a negative number, NaN, inf, or a non-numeric string that float() happens to parse (or the computed value like queries/seconds or peak_heap_bytes ends up non-positive).
Common situations: Missing/placeholder values like 0 or -1 in the CSV; division producing inf/nan from earlier validation gaps; corrupted or truncated measurement output.
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.
Related errors
- heap results require Turso and the requested queries per…
- no query finished on any engine
- no results found
- : no results found
- : unknown or duplicate query
AI-assisted analysis of tursodatabase/turso@8d4a589f8d (2026-09-20).
Data as JSON: /api/errors/f195645f4651aba9.
Report an issue: GitHub.
Appendix: source
Thrown at perf/fts/plot/plot-fts.py:147
value = float(row["peak_heap_bytes"]) / (1024 * 1024)
elif row["benchmark"] == "search":
if not 0 < int(row["connections"]) <= queries or queries != int(row["requested_queries"]):
raise ValueError("search results require at least one sample per connection and the requested query count")
value = float(row[f"{percentile}_ms"])
elif row["benchmark"] == "throughput":
minimum = positive_number(row["min_seconds"])
if seconds < minimum:
raise ValueError("throughput results must meet a positive minimum duration")
value = queries / seconds
else:
raise ValueError("unknown benchmark")
return positive_number(value)
def positive_number(value):
value = float(value)
if not np.isfinite(value) or value <= 0:
raise ValueError("measurements must be finite and positive")
return value
def plot_sweep(configuration, points, output, relative=False):
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter, MaxNLocator, NullLocator
importlib.import_module("scienceplots")
plt.style.use(["science", "no-latex"])
fig, axes = plt.subplots(2, 3, figsize=(11, 8), dpi=300)
connections = list(points)
if relative and (configuration["benchmark"] == "memory" or ("sqlite", "wal") not in points[connections[0]]):
raise ValueError("speedup plots require SQLite timing results")
for index, (query, ax) in enumerate(zip(QUERIES, axes.flat)):
table_rows = []View on GitHub (pinned to 8d4a589f8d)