tursodatabase/turso · error · ValueError

: unknown or duplicate query

Error message

{path}: unknown or duplicate query {query}

What it means

Each (run, engine/mode) pair may contain each known query at most once, and only queries listed in QUERIES are accepted. A row with an unrecognized query name or a duplicate within the same run/series fails this check.

Solutions

  1. Remove duplicate query rows for that run from the CSV
  2. Add the new query name to the QUERIES list in plot-fts.py
  3. Fix the query spelling to match QUERIES

Example fix

// before (CSV)
run1,turso,...,query=lookup
run1,turso,...,query=lookup
// after
run1,turso,...,query=lookup
run2,turso,...,query=lookup
Defensive patterns

Strategy: validation

Validate before calling

def validate_queries(rows):
    seen = set()
    for r in rows:
        key = (r["run"], r["engine"], r["mode"], r["query"])
        if r["query"] not in QUERIES or key in seen:
            raise ValueError(f"unknown or duplicate query {r['query']}")
        seen.add(key)

Type guard

def is_known_unique_query(row, seen) -> bool:
    return row["query"] in QUERIES and (row["run"], row["engine"], row["mode"], row["query"]) not in seen

Try / catch

try:
    configuration, runs = read_runs(path, percentile)
except ValueError as e:
    print(f"dedupe or extend QUERIES: {e}")

Prevention

When it happens

Trigger: CSV has a query name not in QUERIES (typo or new query) or repeats the same query twice for the same run and engine/mode.

Common situations: Concatenating overlapping result files so a run appears twice; renaming queries in the harness without updating QUERIES; duplicated rows from an aborted and restarted run.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

        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:
                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"]):

View on GitHub (pinned to 8d4a589f8d)