{"record":{"id":"344935a89f27963a","repo":"astral-sh/ruff","slug":"found-more-than-one-task-matching-the-given-criter","errorCode":null,"errorMessage":"found more than one task matching the given criteria","messagePattern":"found more than one task matching the given criteria","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/ty_completion_eval/src/main.rs","lineNumber":183,"sourceCode":"\n    let sources = TaskSource::all(&truth)?;\n    match args.command {\n        Command::ShowOne(ref cmd) => {\n            tmp_eval_dir.disable_cleanup(cmd.keep_tmp_dir);\n\n            let Some(source) = sources\n                .iter()\n                .find(|source| cmd.matches_source_task(source))\n            else {\n                anyhow::bail!(\"could not find task named `{}`\", cmd.task_name);\n            };\n            let tasks = source.to_tasks(&tmp_eval_path)?;\n            let matching: Vec<&Task> = tasks.iter().filter(|task| cmd.matches_task(task)).collect();\n            anyhow::ensure!(\n                !matching.is_empty(),\n                \"could not find any tasks matching the given criteria\",\n            );\n            anyhow::ensure!(\n                matching.len() < 2,\n                \"found more than one task matching the given criteria\",\n            );\n            let task = &matching[0];\n            let completions = task.completions()?;\n\n            let mut stdout = std::io::stdout().lock();\n            for (i, c) in completions.iter().enumerate() {\n                write!(stdout, \"{}\", c.name.as_str())?;\n                if let Some(module_name) = c.module_name {\n                    write!(stdout, \" (module: {module_name})\")?;\n                }\n                if task.cursor.answer.matches(c) {\n                    write!(stdout, \" (*, {}/{})\", i + 1, completions.len())?;\n                }\n                writeln!(stdout)?;\n            }\n            writeln!(stdout, \"-----\")?;","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/astral-sh/ruff/blob/672bb4edf04c84f8b0753346359daee4057158f2/crates/ty_completion_eval/src/main.rs#L165-L201","documentation":"The inverse of the empty-match guard: `show-one` must resolve to exactly one task, so filters matching two or more `<CURSOR>` directives abort here. Because an omitted filter matches every task, specifying only the fixture (or only a file with multiple directives) is ambiguous by design — add `--file-name` and `--index` until exactly one task remains.","triggerScenarios":"Omitting both `--file-name` and `--index` in a fixture with more than one cursor directive; specifying only `--file-name` when that file contains multiple `<CURSOR>` markers.","commonSituations":"Quick inspection runs where the developer expects `show-one` to default to the first task; fixtures grown over time so a previously-unique file filter now matches several cursors.","solutions":["Add `--file-name` if you only specified the fixture name","Add `--index` (zero-based, per the CSV) if the file still matches multiple cursors","Consult the CSV rows for that fixture to choose a unique (file, index) pair"],"exampleFix":"# before (file has multiple cursors; ambiguous)\ncargo run -p ty_completion_eval -- show-one custom-types --file-name main.py\n# after\ncargo run -p ty_completion_eval -- show-one custom-types --file-name main.py --index 0","handlingStrategy":"validation","validationCode":"n=$(grep -c '<CURSOR' \"$FIXTURE_FILE\")\n[ \"$n\" -le 1 ] || echo \"this file has $n cursors; pass --index too\" >&2","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass both `--file-name` and `--index` to `show-one`","Treat ambiguity as a prompt to inspect the CSV, not to guess","Re-check filters after fixtures gain new cursor directives"],"tags":["evaluation","cli","validation","filters"],"backgroundTag":null,"analyzedSha":"672bb4edf04c84f8b0753346359daee4057158f2","analyzedAt":"2026-08-16T08:54:05.464Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}