can1357/oh-my-pi · error · StatError

{directive}: invalid directive

Error message

{directive}: invalid directive

What it means

StatError::InvalidDirective is thrown when the --printf/--format string contains a format directive stat does not recognize. The full offending directive is echoed back so the user can locate it in their format string; this typically means a typo or a directive supported only by another stat implementation.

Source

Thrown at crates/pi-builtins/src/stat.rs:140

-`%i`: file system ID in hex
-`%l`: maximum length of filenames
-`%n`: file name
-`%s`: block size (for faster transfers)
-`%S`: fundamental block size (for block counts)
-`%t`: file system type in hex
-`%T`: file system type in human readable form

NOTE: your shell may have its own version of stat, which usually supersedes
the version described here.  Please refer to your shell's documentation
for details about the options it supports.";

	#[derive(Debug, Error)]
	enum StatError {
		#[error("Invalid quoting style: {style}")]
		InvalidQuotingStyle { style: String },
		#[error("missing operand\nTry 'stat --help' for more information.")]
		MissingOperand,
		#[error("{directive}: invalid directive")]
		InvalidDirective { directive: String },
		#[error("cannot read table of mounted file systems: {error}")]
		#[cfg_attr(not(unix), allow(dead_code, reason = "mount tables are unix-only"))]
		CannotReadFilesystem { error: String },
		#[error("using '-' to denote standard input does not work in file system mode")]
		#[cfg_attr(not(unix), allow(dead_code, reason = "stdin filesystem mode is unix-only"))]
		StdinFilesystemMode,
		#[error("cannot read file system information for {file}: {error}")]
		CannotReadFilesystemInfo { file: String, error: String },
		#[error("cannot stat {file}: {error}")]
		CannotStat { file: String, error: String },
	}

	mod options {
		pub const DEREFERENCE: &str = "dereference";
		pub const FILE_SYSTEM: &str = "file-system";
		pub const FORMAT: &str = "format";
		pub const PRINTF: &str = "printf";

View on GitHub (pinned to 9690622007)

Solutions

  1. Check the directive letter against the stat builtin's documented directive list and fix or remove it.
  2. Read the full message to identify which directive was rejected and correct the format string.
  3. Test the format string incrementally (one directive at a time) to isolate the bad one.
  4. Escape a literal percent as %% if a percent sign was intended rather than a directive.

Example fix

// before
stat --printf='%z\n' file.txt   // unsupported directive
// after
stat --printf='%s\n' file.txt   // use a supported directive
Defensive patterns

Strategy: validation

Validate before calling

// allow-list of supported stat directives; validate the format before use
const SUPPORTED = new Set(["n", "s", "F", "A", "a", "b", "c", "d", "f", "g", "i", "h", "m", "t", "u", "W", "X", "Y", "Z", "%"]);
const directives = [...fmt.matchAll(/%(.)|%%/g)].map(m => m[1]);
const bad = directives.filter(d => !SUPPORTED.has(d));
if (bad.length) throw new Error(`unsupported directives: ${bad.join("")}`);

Type guard

const isSupportedDirective = (d: string): boolean => SUPPORTED_DIRECTIVES.has(d);

Try / catch

try {
  await stat(["--printf=" + fmt, file]);
} catch (err) {
  const m = String(err).match(/^(.+): invalid directive$/);
  if (m) {
    const fixed = fmt.replace(m[1], ""); // strip the rejected directive and retry
    return stat(["--printf=" + fixed, file]);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling the stat builtin with a format containing an invalid %-directive, e.g. `stat --printf='%z\n' file` where %z is not supported, or a malformed sequence like '%Q'.

Common situations: Copy-pasting format strings from GNU stat variants with extra directives; typos in directive letters; scripts migrated between macOS/BSD stat and GNU-style stat; hand-edited format templates.

Related errors


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