tursodatabase/turso · error · ValueError

no results found

Error message

no results found

What it means

At the end of read_runs, if no input file produced a configuration (empty path list or nothing parsed), the function raises this ValueError instead of returning an empty plot dataset. It protects main from charting nonexistent results.

Solutions

  1. Pass at least one non-empty benchmark results CSV to plot-fts.py.
  2. Verify the file paths/glob resolve to existing result files.
  3. Run the FTS benchmark to produce results before plotting.

Example fix

# before
python plot-fts.py
# after
python plot-fts.py results/run1.csv results/run2.csv
Defensive patterns

Strategy: validation

Validate before calling

import os
paths = [p for p in argv_paths if os.path.getsize(p) > 0]
assert paths, 'no non-empty benchmark result files supplied'

Try / catch

try:
    config, samples = read_runs(paths)
except ValueError as e:
    if 'no results found' in str(e):
        print('Fix: supply at least one non-empty results CSV to plot-fts.py')
    else:
        raise

Prevention

When it happens

Trigger: Calling read_runs (via main) with zero CSV paths or paths that yield no rows/configuration.

Common situations: plot-fts.py invoked on an empty results directory; wrong path pattern on the command line; CSV files that are empty or header-only.

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


AI-assisted analysis of tursodatabase/turso@8d4a589f8d (2026-09-20). Data as JSON: /api/errors/9f46e6559b83caec. Report an issue: GitHub.

Appendix: source

Thrown at perf/fts/plot/plot-fts.py:84


def read_runs(paths, percentile="p50"):
    configuration = None
    samples = {}
    expected_series = None
    for path in paths:
        current, runs = read_file(path, percentile, samples)
        if configuration is None:
            configuration = current
        if configuration != current:
            raise ValueError("plot only one configuration at a time")
        for run in runs.values():
            if expected_series is None:
                expected_series = set(run)
            if set(run) != expected_series or any(seen != set(QUERIES) for seen in run.values()):
                raise ValueError(f"{path}: each run must contain the same series and all six query cases")
    if configuration is None:
        raise ValueError("no results found")
    configuration = dict(zip(CONFIGURATION, configuration))
    configuration["percentile"] = percentile
    return configuration, samples


def read_file(path, percentile, samples):
    configuration = None
    runs = {}
    with path.open(newline="") as stream:
        reader = csv.DictReader(stream)
        required = set(CONFIGURATION) | {"engine", "mode", "run", "query", "queries"}
        if not required <= set(reader.fieldnames or []):
            raise ValueError(f"{path}: missing benchmark columns")
        for row in reader:
            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:

View on GitHub (pinned to 8d4a589f8d)