pbakaus/impeccable · error

Error: cannot scan {target}: {message}

Error message

Error: cannot scan {target}: {message}

What it means

`Ctx::report_local_scan_failure` marks the run as having an operational failure and prints `Error: cannot scan <target>: <message>` to stderr. It is the Rust port of main.mjs#reportLocalScanFailure and centralizes reporting for local-path scan targets that could not be scanned (unreadable files, bad paths, IO errors). The exit code / result handling treats `had_operational_failure = true` as a failed run even if other targets succeeded.

Source

Thrown at crates/detect/src/cli.rs:250

    cwd: String,
    home: String,
    config: DetectionConfig,
    json_mode: bool,
    quiet_mode: bool,
    design_system_enabled: bool,
    base: ScanOptions,
    cache: DesignSystemCache,
    stdin_tty: bool,
    /// JS `hadOperationalFailure`: at least one requested target could not be
    /// scanned, which forces exit 1 (#711).
    had_operational_failure: bool,
}

impl<'a> Ctx<'a> {
    /// JS: main.mjs#reportLocalScanFailure
    fn report_local_scan_failure(&mut self, target: &str, message: &str) {
        self.had_operational_failure = true;
        self.io.err(&format!("Error: cannot scan {target}: {message}\n"));
    }

    fn scan_options_for(&mut self, local_path: Option<&str>) -> ScanOptions {
        let (Some(local_path), true) = (local_path, self.design_system_enabled) else {
            return self.base.clone();
        };
        match load_design_system_for_target(
            local_path,
            Some(&mut self.cache),
            &self.cwd,
            &self.home,
        ) {
            Some(ds) => ScanOptions {
                design_system: Some(ds),
                ..self.base.clone()
            },
            None => self.base.clone(),
        }

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Verify the target path exists: `ls -la <target>`, and re-run with the correct relative or absolute path.
  2. Fix file permissions (`chmod u+r <file>` / `chown`) or run from a directory where the path is readable.
  3. If the message body indicates an internal scan error, reproduce with a minimal file and report it; meanwhile exclude the broken target from the target list.

Example fix

// before
impeccable detect src/page.htm   // typo: file not found
// after
impeccable detect src/page.html
Defensive patterns

Strategy: validation

Validate before calling

import fs from "node:fs";
for (const t of targets) {
  if (!fs.existsSync(t) || !fs.accessSync(t, fs.constants.R_OK)) {
    throw new Error(`target not readable: ${t}`);
  }
}

Try / catch

const r = spawnSync("impeccable", ["detect", target]);
if (r.status !== 0 && r.stderr.toString().startsWith("Error: cannot scan")) {
  console.error(`Skipping unreadable target ${target}; check path/permissions.`);
}

Prevention

When it happens

Trigger: Calling `impeccable detect <path>` where the local target cannot be scanned: the path does not exist, lacks read permission, is an unreadable special file, or the scanner returns an error message for that target. Any per-target scan error for a local path routes here.

Common situations: Typos in the file/directory path; running from the wrong working directory so a relative path resolves elsewhere; CI checkouts missing the file; permission-restricted files (e.g. created by another user); passing a directory where only files are accepted or vice versa.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/fe8051b82d4b2581. Report an issue: GitHub.