{"record":{"id":"9bff52c9e5f649c8","repo":"pbakaus/impeccable","slug":"aborted","errorCode":null,"errorMessage":"Aborted.\n","messagePattern":"Aborted\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/detect/src/cli.rs","lineNumber":756,"sourceCode":"                walk_failures.push((dir.to_string(), node_scan_error(dir, err)));\n            })\n            .into_iter()\n            .filter(|f| !should_ignore_detection_file(f, &cwd, &ctx.config))\n            .collect();\n            for (dir, message) in walk_failures {\n                ctx.report_local_scan_failure(&dir, &message);\n            }\n            let html_count = files.iter().filter(|f| is_html_path(f)).count();\n            if files.len() > 50 && ctx.stdin_tty && !ctx.json_mode && !ctx.quiet_mode {\n                ctx.io.err(&format!(\n                    \"\\nFound {} files ({} HTML) in {}.\\nScanning may take a while{}.\\nTarget a specific subdirectory to narrow scope.\\n\",\n                    files.len(),\n                    html_count,\n                    target,\n                    if html_count > 10 { \" (static HTML/CSS processes each HTML file individually)\" } else { \"\" }\n                ));\n                if !confirm(ctx.io, \"Continue?\") {\n                    ctx.io.err(\"Aborted.\\n\");\n                    return Err(Exit(0));\n                }\n            }\n            let mut unreadable_files: Vec<String> = Vec::new();\n            let mut read_failures: Vec<(String, String)> = Vec::new();\n            let graph = build_import_graph_reporting(&files, &mut |file, err| {\n                unreadable_files.push(file.to_string());\n                read_failures.push((file.to_string(), node_scan_error(file, err)));\n            });\n            for (file, message) in read_failures {\n                ctx.report_local_scan_failure(&file, &message);\n            }\n            let mut imported_by_map: Vec<(String, Vec<String>)> = Vec::new();\n            for (importer, imports) in &graph {\n                for imported in imports {\n                    if let Some(slot) = imported_by_map.iter_mut().find(|(k, _)| k == imported) {\n                        if !slot.1.contains(importer) {\n                            slot.1.push(importer.clone());","sourceCodeStart":738,"sourceCodeEnd":774,"githubUrl":"https://github.com/pbakaus/impeccable/blob/2bc2879276c1f321a53c4ca99d3371e411329b52/crates/detect/src/cli.rs#L738-L774","documentation":"When a directory target contains more than 50 files and stdin is an interactive TTY (non-JSON, non-quiet mode), scan_targets warns that the scan may take a while and calls confirm(\"Continue?\"). If the user answers anything interpreted as \"no\", it prints \"Aborted.\" to stderr and returns Err(Exit(0)) — the scan is cancelled by explicit user choice, with exit code 0, not an error condition.","triggerScenarios":"Running `impeccable detect <dir>` on a directory whose file list (after ignore filtering) exceeds 50 entries, with a TTY on stdin, and typing 'n' (or Enter-then-no semantics) at the \"Continue? [Y/n]\" prompt.","commonSituations":"Accidentally pointing detect at a huge directory like node_modules-adjacent output or a whole repo root; an interactive CI/PTY wrapper auto-answering the prompt; pressing Enter expecting the default Y but the terminal session sent something else.","solutions":["Re-run and answer 'Y' (or just accept the default) at the Continue? prompt","Narrow the target to a specific subdirectory so the file count stays under 50 and the prompt is skipped","Run with --quiet or --json mode to bypass the interactive confirmation entirely","Pipe/redirect stdin (non-TTY) in scripts so the prompt path is not taken"],"exampleFix":"// before\n$ impeccable detect .\nFound 512 files (30 HTML) in .\nContinue? [Y/n] n\nAborted.\n\n// after\n$ impeccable detect ./src/components  # narrower scope, no prompt","handlingStrategy":"fallback","validationCode":"// Count files first to anticipate the prompt\nconst count = require('child_process')\n  .execSync('find <dir> -type f | wc -l').toString().trim();\nif (Number(count) > 50) console.log('scan will prompt for confirmation');","typeGuard":null,"tryCatchPattern":"// Treat exit code 0 with 'Aborted.' on stderr as user cancellation\nconst res = spawnSync('impeccable', ['detect', dir]);\nif (res.status === 0 && /Aborted\\./.test(res.stderr.toString())) {\n  // scan was cancelled at the confirm prompt — not a scan failure\n}","preventionTips":["Use --json or --quiet for non-interactive runs to skip the prompt","Keep scan targets under 50 files by targeting subdirectories","Ensure CI does not allocate a TTY unless it can answer prompts"],"tags":["cli","interactive","abort"],"backgroundTag":"operation-aborted-by-user","analyzedSha":"2bc2879276c1f321a53c4ca99d3371e411329b52","analyzedAt":"2026-09-08T04:51:14.109Z","contentChangedAt":"2026-09-08T04:51:14.109Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}