{"record":{"id":"cc3b1694731c455b","repo":"nikivdev/code","slug":"could-not-parse-task-name-from-ai-response","errorCode":null,"errorMessage":"Could not parse task name from AI response: '{}'","messagePattern":"Could not parse task name from AI response: '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ask.rs","lineNumber":682,"sourceCode":"            .to_lowercase()\n            .contains(&task.task.name.to_lowercase())\n        {\n            return Ok(task.task.name.clone());\n        }\n    }\n\n    let cleaned = response\n        .trim_start_matches(|c: char| !c.is_alphanumeric())\n        .trim_end_matches(|c: char| !c.is_alphanumeric() && c != '-' && c != '_')\n        .to_string();\n\n    for task in tasks {\n        if task.task.name.eq_ignore_ascii_case(&cleaned) {\n            return Ok(task.task.name.clone());\n        }\n    }\n\n    bail!(\"Could not parse task name from AI response: '{}'\", response)\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::config::TaskConfig;\n\n    fn make_discovered(name: &str) -> DiscoveredTask {\n        DiscoveredTask {\n            task: TaskConfig {\n                name: name.to_string(),\n                command: format!(\"echo {}\", name),\n                delegate_to_hub: false,\n                activate_on_cd_to_root: false,\n                dependencies: Vec::new(),\n                description: None,\n                shortcuts: Vec::new(),\n                interactive: false,","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ask.rs#L664-L700","documentation":"extract_task_name matches the cleaned AI response against discovered task names (case-insensitive exact match). When no task name matches, it bails with the original response so the developer can see what the model returned. It is reached via the 'task:' structured prefix or the bare-text fallback in parse_ask_response.","triggerScenarios":"AI answers 'task: build-prod' when the task is named 'build_prod' or 'build prod'; 'task:' prefix with a description instead of the name; bare-text answer that mentions a task but isn't an exact name; the task was removed/renamed after discovery.","commonSituations":"Model paraphrases task names; hyphen/underscore mismatch (only eq_ignore_ascii_case is applied, not the normalize_name fuzzy match used elsewhere); stale cached task list.","solutions":["Apply normalize_name (strip '-', '_', lowercase) to both sides before comparing, matching how other lookups in the file work","Log the response and the available task list, then re-prompt the AI to answer with an exact task name","Confirm the tasks passed to parse_ask_response are current (re-run discovery)","Fall back to interactive task selection when no match is found"],"exampleFix":"// before\nfor task in tasks {\n    if task.task.name.eq_ignore_ascii_case(&cleaned) {\n        return Ok(task.task.name.clone());\n    }\n}\n// after\nlet wanted = normalize_name(&cleaned);\nfor task in tasks {\n    if normalize_name(&task.task.name) == wanted {\n        return Ok(task.task.name.clone());\n    }\n}\nbail!(\"Could not parse task name from AI response: '{}'\", response);","handlingStrategy":"fallback","validationCode":"fn task_name_is_known(name: &str, tasks: &[DiscoveredTask]) -> bool {\n    tasks.iter().any(|t| t.task.name.eq_ignore_ascii_case(name.trim()))\n}","typeGuard":null,"tryCatchPattern":"match extract_task_name(cleaned, tasks) {\n    Err(_) => {\n        eprintln!(\"Could not match a task; choose one manually:\");\n        prompt_task_selection(tasks)\n    }\n    Ok(name) => name,\n}","preventionTips":["Use normalize_name (strip -/_, lowercase) on both sides for tolerant matching","Refresh the discovered task list before each ask","Prompt the AI to answer with an exact task name from the provided list","Provide an interactive picker as fallback"],"tags":["ai","parsing","task-discovery"],"backgroundTag":"unparseable-llm-response","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}