can1357/oh-my-pi · error · BindError

I/O error occurred

Error message

I/O error occurred

What it means

`BindError::IoError` wraps a `std::io::Error` (via `#[from]`) encountered by the `bind` builtin, typically while reading a bindings file passed with `-f` or other file/stdin access. The displayed message is intentionally generic — the underlying OS error detail is lost in the formatted output, though it remains in the variant payload.

Source

Thrown at crates/pi-builtins/src/bind.rs:104

	key_sequence: Option<String>,
}

#[derive(Debug, thiserror::Error)]
pub(crate) enum BindError {
	/// Unknown function specified.
	#[error("unknown function: {0}")]
	UnknownFunction(String),

	/// Unknown key binding function.
	#[error("unknown key binding function: {0}")]
	UnknownKeyBindingFunction(String),

	/// Unimplemented functionality.
	#[error("unimplemented: {0}")]
	Unimplemented(&'static str),

	/// An I/O error occurred.
	#[error("I/O error occurred")]
	IoError(#[from] std::io::Error),

	/// A binding parse error occurred.
	#[error(transparent)]
	BindingParseError(#[from] brush_parser::BindingParseError),
}

impl brush_core::BuiltinError for BindError {}

impl From<&BindError> for brush_core::ExecutionExitCode {
	fn from(_err: &BindError) -> Self {
		Self::GeneralError
	}
}

impl builtins::Command for BindCommand {
	type Error = BindError;

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify the file path passed to `bind -f` exists and is readable (`ls -l`, `cat` it manually).
  2. Fix file permissions or run under a user with access.
  3. If the detail matters, run with debug/tracing enabled (trace_categories in brush) to capture the wrapped io::Error.

Example fix

// before
$ bind -f ~/.inputrc-bak
I/O error occurred
// after
$ ls ~/.inputrc*   # find the real filename
$ bind -f ~/.inputrc.backup
Defensive patterns

Strategy: try-catch

Validate before calling

// shell-level: confirm the bindings file is readable first
BIND_FILE=~/.inputrc
if [ ! -r "$BIND_FILE" ]; then
  echo "cannot read bindings file: $BIND_FILE" >&2
  exit 1
fi
bind -f "$BIND_FILE"

Type guard

// Rust caller pattern: match on the variant before handling
if let BindError::IoError(io) = &err {
    eprintln!("bind I/O failure: {io}");
}

Try / catch

// shell: tolerate bind import failure without killing the session
if ! bind -f ~/.inputrc; then
  echo "warning: failed to load key bindings" >&2
fi

Prevention

When it happens

Trigger: `bind -f PATH` where PATH cannot be opened (missing file, permission denied); any read/write on a bindings file or terminal fd that fails with an io::Error propagated via the `?`/`#[from]` conversion.

Common situations: Typo in the `-f` bindings file path; file exists but the shell user lacks read permission; trying to import a directory instead of a file; scripts assuming a bindings file was created by an earlier step but it was not.

Understand the failure class

Background: Rust io::Error: what ErrorKind::NotFound, PermissionDenied, and InvalidData actually mean — from real OS failures to library fail-closed refusals — this error's family across 12 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/0c0c7bc8d023a2d3. Report an issue: GitHub.