can1357/oh-my-pi · error · LsError

--dired and --zero are incompatible

Error message

--dired and --zero are incompatible

What it means

LsError::DiredAndZeroAreIncompatible is raised when the builtin `ls` is invoked with both --dired and --zero. --dired emits per-file `//DIRED//` position markers for Emacs, which are meaningless (and would be wrong) when records are terminated by NUL instead of newline via --zero. The library rejects the combination up front, like GNU coreutils.

Source

Thrown at crates/pi-builtins/src/ls.rs:3705

			1 => format!("cannot access {}: Operation not permitted", .0.quote()),
			_ => if *.3 {
				format!("cannot open directory {}: Permission denied", .0.quote())
			} else {
				format!("cannot open file {}: Permission denied", .0.quote())
			},
		},
		_ => if 9 == .1.raw_os_error().unwrap_or(1) {
			format!("cannot open directory {}: Bad file descriptor", .0.quote())
		} else {
			format!("unknown io error: {}, '{:?}'", .0.quote(), .1)
		},
	})]
	IOErrorContext(PathBuf, std::io::Error, bool, bool),

	#[error("invalid --block-size argument '{0}'")]
	BlockSizeParseError(String),

	#[error("--dired and --zero are incompatible")]
	DiredAndZeroAreIncompatible,

	#[error("{}: not listing already-listed directory", .0.maybe_quote())]
	AlreadyListedError(PathBuf),

	#[error("invalid --time-style argument {}\nPossible values are:\n  - [posix-]full-iso\n  - [posix-]long-iso\n  - [posix-]iso\n  - [posix-]locale\n  - +FORMAT (e.g., +%H:%M) for a 'date'-style format\n\nFor more information try --help", .0.quote())]
	TimeStyleParseError(String),
}

impl LsError {
	fn code(&self) -> i32 {
		match self {
			Self::InvalidLineWidth(_) => 2,
			Self::IOError(_) => 1,
			Self::IOErrorContext(_, _, false, _) => 1,
			Self::IOErrorContext(_, _, true, _) => 2,
			Self::BlockSizeParseError(_) => 2,
			Self::DiredAndZeroAreIncompatible => 2,

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove --dired if you need machine-parseable NUL-delimited output (--zero)
  2. Remove --zero if you need Emacs dired position markers (--dired)
  3. Check aliases and LS_OPTIONS / ls wrapper scripts for an implicit --zero or --dired
  4. Use plain tab/newline output if neither feature is actually needed

Example fix

// before
ls --dired --zero
// after
ls --dired   // Emacs dired markers
// or
ls --zero    // NUL-delimited for xargs -0
Defensive patterns

Strategy: validation

Validate before calling

if (opts.includes('--dired') && opts.includes('--zero')) {
  throw new Error('--dired and --zero are incompatible: pick one output convention');
}

Type guard

const hasConflictingOutputFlags = (flags: string[]): boolean =>
  flags.includes('--dired') && flags.includes('--zero');

Try / catch

try {
  runLs(allFlags);
} catch (e) {
  if (String(e).includes('--dired and --zero are incompatible')) {
    runLs(allFlags.filter(f => f !== '--dired'));
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the ls builtin with both flags, e.g. `ls --dired --zero` or `ls -N --zero --dired` where one flag is set via an alias or LS_OPTIONS env var.

Common situations: Emacs dired-mode integration colliding with null-delimited output for `xargs -0` pipelines; shell aliases that always add --zero; combining options from two different sources without noticing the overlap.

Related errors


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