Hmbown/CodeWhale · error

private sidecar file

Error message

private sidecar file {path} must be regular

What it means

On platforms other than Unix or Windows (cfg(all(not(unix), not(windows)))), session_manager performs a minimal check that the private sidecar file is a regular file via metadata().is_file(). Directories, devices, FIFOs, or other special files at the sidecar path are rejected with InvalidData.

Solutions

  1. Check what is at the path and remove/replace the non-regular entry (e.g. `rm` a fifo/device or `rmdir` a directory).
  2. Point the session store at a normal directory on a regular filesystem.
  3. If you control the platform support, add an explicit validation branch for it.

Example fix

// before: a directory exists where the sidecar file is expected
ls sessions/session.lock  // is a directory
// after: remove it and let Codewhale create a real file
rmdir sessions/session.lock
Defensive patterns

Strategy: validation

Validate before calling

if !std::fs::metadata(path).map(|m| m.is_file()).unwrap_or(false) {
    return Err(format!("{} must be a regular file", path.display()));
}

Try / catch

match open_private_lock_file(path) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => eprintln!("path is not a regular file: {e}"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling open_private_lock_file or open_private_read_file on a non-Unix, non-Windows target when the path exists but its metadata is_file() is false (e.g. it is a directory or special file).

Common situations: A directory accidentally occupies the expected sidecar filename; a custom platform/embedded filesystem returns unusual file types; tests on exotic targets point the session path at a special node.

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 Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/7331a7403441e305. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/session_manager.rs:240

    if unsafe { GetFileInformationByHandle(file.as_raw_handle(), &mut info) } == 0 {
        return Err(io::Error::last_os_error());
    }
    if info.nNumberOfLinks != 1 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "private sidecar file {} must have exactly one filesystem link",
                path.display()
            ),
        ));
    }
    Ok(())
}

#[cfg(all(not(unix), not(windows)))]
fn validate_private_regular_file(file: &fs::File, path: &Path) -> io::Result<()> {
    if !file.metadata()?.is_file() {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!("private sidecar file {} must be regular", path.display()),
        ));
    }
    Ok(())
}

/// Persisted queued message for offline/degraded mode.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueuedSessionMessage {
    pub display: String,
    #[serde(default)]
    pub skill_instruction: Option<String>,
    #[serde(default)]
    pub skill_provenance: Option<crate::plugins::types::PluginAuthority>,
}

/// Persisted queue state for recovery after restart/crash.

View on GitHub (pinned to 73e0f67d83)