tursodatabase/turso · error · ValueError
: no results found
Error message
{path}: no results found What it means
After parsing every row of the benchmark CSV, no valid result rows were collected for the file, so there is nothing to plot. The guard fires when the CSV is empty, all rows were rejected by earlier checks (e.g. unsupported engine/mode or profiled rows), or the file only contains header/columns.
Solutions
- Point the script at a results CSV that actually contains data rows
- Re-run the benchmark to produce results
- Check the benchmark output path/arguments if the file is unexpectedly empty
Defensive patterns
Strategy: validation
Validate before calling
import csv
with open(path) as f:
if sum(1 for _ in csv.DictReader(f)) == 0:
raise ValueError(f"{path}: no results found") Type guard
def has_data_rows(path) -> bool:
with open(path) as f:
return next(csv.DictReader(f), None) is not None Try / catch
try:
configuration, runs = read_runs(path, percentile)
except ValueError as e:
print(f"no data to plot: {e}") Prevention
- Confirm the benchmark run completed before plotting
- Check file size/line count before passing a results file
- Verify the output path argument of the benchmark harness
When it happens
Trigger: CSV has a header but zero data rows; a filter or generator wrote only the header; wrong file passed in.
Common situations: Benchmark crashed before writing results; glob picked up an empty template CSV; all rows were removed while cleaning duplicates.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- no results found
- heap results require Turso and the requested queries per…
- measurements must be finite and positive
- no query finished on any engine
- no results found
AI-assisted analysis of tursodatabase/turso@8d4a589f8d (2026-09-20).
Data as JSON: /api/errors/283fd51468af8c47.
Report an issue: GitHub.
Appendix: source
Thrown at perf/fts/plot/plot-fts.py:117
if row.get("profiled", "false") != "false":
raise ValueError("profiled timings must not be used for benchmark comparisons")
current = tuple(row[key] for key in CONFIGURATION)
if configuration is None:
configuration = current
if configuration != current:
raise ValueError("plot only one configuration at a time")
key = (row["engine"], row["mode"])
if key not in SERIES:
raise ValueError(f"unsupported engine/mode: {key}")
series = samples.setdefault(key, {query: [] for query in QUERIES})
query = row["query"]
seen = runs.setdefault(row["run"], {}).setdefault(key, set())
if query not in QUERIES or query in seen:
raise ValueError(f"{path}: unknown or duplicate query {query}")
seen.add(query)
series[query].append(read_measurement(row, percentile))
if not runs:
raise ValueError(f"{path}: no results found")
return configuration, runs
def read_measurement(row, percentile):
queries = int(row["queries"])
positive_number(queries)
if row["benchmark"] != "memory":
seconds = positive_number(row["seconds"])
if row["benchmark"] == "memory":
if row["engine"] != "turso" or queries != int(row["requested_queries"]) * int(row["connections"]):
raise ValueError("heap results require Turso and the requested queries per connection")
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"])View on GitHub (pinned to 8d4a589f8d)