can1357/oh-my-pi · error · MkTempError

invalid template, {}, contains directory separator

Error message

invalid template, {}, contains directory separator

What it means

MkTempError::PrefixContainsDirSeparator is raised when the template portion of a mktemp argument contains a directory separator ('/'). The template's fixed part is treated as a filename prefix within the target directory; embedding a path separator would make the prefix attempt to traverse directories, which the tool forbids.

Source

Thrown at crates/pi-builtins/src/mktemp.rs:63

#[cfg(not(windows))]
const TMPDIR_ENV_VAR: &str = "TMPDIR";
#[cfg(windows)]
const TMPDIR_ENV_VAR: &str = "TMP";

const FALLBACK_TMPDIR: &str = "/tmp";

#[derive(Error, Debug)]
enum MkTempError {
	#[error("could not persist file {}", .0.quote())]
	Persist(PathBuf),

	#[error("with --suffix, template {} must end in X", .0.quote())]
	MustEndInX(String),

	#[error("too few X's in template {}", .0.quote())]
	TooFewXs(String),

	#[error("invalid template, {}, contains directory separator", .0.quote())]
	PrefixContainsDirSeparator(String),

	#[error("invalid suffix {}, contains directory separator", .0.quote())]
	SuffixContainsDirSeparator(String),

	#[error("invalid template, {}; with --tmpdir, it may not be absolute", .0.quote())]
	InvalidTemplate(OsString),

	#[error("too many templates")]
	TooManyTemplates,

	#[error("failed to create {} via template {}: No such file or directory", .0, .1.quote())]
	NotFound(String, PathBuf),

	#[error(transparent)]
	Io(#[from] io::Error),
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Move the directory portion to --tmpdir: `mktemp --tmpdir="$dir" tmpXXXXXX`
  2. Strip leading/trailing path components from the template before passing it
  3. If a subdirectory structure is needed, create it separately (mkdir) and use --tmpdir pointing into it
  4. Sanitize user input used as a template: reject or split on '/'

Example fix

// before
mktemp "$dir/tmpXXXXXX"
// after
mktemp --tmpdir="$dir" tmpXXXXXX
Defensive patterns

Strategy: validation

Validate before calling

if (template.includes('/')) {
  const dir = path.dirname(template);
  const base = path.basename(template);
  // use: mktemp --tmpdir="${dir}" "${base}"
  throw new RangeError(`template '${template}' must not contain '/'; pass the dir via --tmpdir`);
}

Type guard

const isPlainFilenameTemplate = (t: string): boolean => !t.includes('/');

Try / catch

try {
  await Bun.$`mktemp ${tmpl}`.quiet();
} catch (e) {
  if (String(e).includes('contains directory separator')) {
    const dir = path.dirname(tmpl), base = path.basename(tmpl);
    await Bun.$`mktemp --tmpdir=${dir} ${base}`.quiet();
  } else throw e;
}

Prevention

When it happens

Trigger: `mktemp dir/tmpXXXXXX` without --tmpdir semantics — pass directories only via --tmpdir, not inside the template; templates built by string-concatenating a directory path onto a filename.

Common situations: Scripts doing `mktemp "$dir/tmpXXXX"` instead of `mktemp -p "$dir" tmpXXXX`; user-supplied paths pasted wholesale into the template; Windows-style separators slipping in.

Related errors


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