{"record":{"id":"9f46e6559b83caec","repo":"tursodatabase/turso","slug":"no-results-found-plot-fts","errorCode":null,"errorMessage":"no results found","messagePattern":"no results found","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"perf/fts/plot/plot-fts.py","lineNumber":84,"sourceCode":"\n\ndef read_runs(paths, percentile=\"p50\"):\n    configuration = None\n    samples = {}\n    expected_series = None\n    for path in paths:\n        current, runs = read_file(path, percentile, samples)\n        if configuration is None:\n            configuration = current\n        if configuration != current:\n            raise ValueError(\"plot only one configuration at a time\")\n        for run in runs.values():\n            if expected_series is None:\n                expected_series = set(run)\n            if set(run) != expected_series or any(seen != set(QUERIES) for seen in run.values()):\n                raise ValueError(f\"{path}: each run must contain the same series and all six query cases\")\n    if configuration is None:\n        raise ValueError(\"no results found\")\n    configuration = dict(zip(CONFIGURATION, configuration))\n    configuration[\"percentile\"] = percentile\n    return configuration, samples\n\n\ndef read_file(path, percentile, samples):\n    configuration = None\n    runs = {}\n    with path.open(newline=\"\") as stream:\n        reader = csv.DictReader(stream)\n        required = set(CONFIGURATION) | {\"engine\", \"mode\", \"run\", \"query\", \"queries\"}\n        if not required <= set(reader.fieldnames or []):\n            raise ValueError(f\"{path}: missing benchmark columns\")\n        for row in reader:\n            if row.get(\"profiled\", \"false\") != \"false\":\n                raise ValueError(\"profiled timings must not be used for benchmark comparisons\")\n            current = tuple(row[key] for key in CONFIGURATION)\n            if configuration is None:","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/tursodatabase/turso/blob/8d4a589f8d13ac184700d2a8f724f27e1995be3b/perf/fts/plot/plot-fts.py#L66-L102","documentation":"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.","triggerScenarios":"Calling read_runs (via main) with zero CSV paths or paths that yield no rows/configuration.","commonSituations":"plot-fts.py invoked on an empty results directory; wrong path pattern on the command line; CSV files that are empty or header-only.","solutions":["Pass at least one non-empty benchmark results CSV to plot-fts.py.","Verify the file paths/glob resolve to existing result files.","Run the FTS benchmark to produce results before plotting."],"exampleFix":"# before\npython plot-fts.py\n# after\npython plot-fts.py results/run1.csv results/run2.csv","handlingStrategy":"validation","validationCode":"import os\npaths = [p for p in argv_paths if os.path.getsize(p) > 0]\nassert paths, 'no non-empty benchmark result files supplied'","typeGuard":null,"tryCatchPattern":"try:\n    config, samples = read_runs(paths)\nexcept ValueError as e:\n    if 'no results found' in str(e):\n        print('Fix: supply at least one non-empty results CSV to plot-fts.py')\n    else:\n        raise","preventionTips":["Verify result files exist and are non-empty before plotting.","Fail fast in scripts when the benchmark produced no output.","Run the benchmark to completion before invoking the plotter."],"tags":["python","benchmarking","empty-input"],"backgroundTag":"empty-result-set","analyzedSha":"8d4a589f8d13ac184700d2a8f724f27e1995be3b","analyzedAt":"2026-09-20T13:18:14.658Z","contentChangedAt":"2026-09-20T13:18:14.658Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}