can1357/oh-my-pi · error · MkTempError

invalid template, {}; with --tmpdir, it may not be absolute

Error message

invalid template, {}; with --tmpdir, it may not be absolute

What it means

MkTempError::InvalidTemplate is raised when the mktemp template is an absolute path but --tmpdir was also given. The two are contradictory: an absolute template already fully specifies the location, while --tmpdir would relocate it, so the tool refuses the ambiguous combination.

Source

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

#[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),
}

/// Options parsed from the command line.
///
/// This provides a layer of indirection between the application logic and
/// `clap`, allowing each to vary independently.
#[derive(Clone)]
struct Options {

View on GitHub (pinned to 9690622007)

Solutions

  1. Drop --tmpdir when the template is absolute (it already encodes the directory)
  2. Convert the template to a bare filename and pass the directory via --tmpdir
  3. In wrappers, detect absolute templates and omit the injected --tmpdir: only add --tmpdir when the template is relative
  4. Validate inputs before composing the command: if template starts with '/', skip the flag

Example fix

// before
mktemp --tmpdir=/var/tmp /tmp/fooXXXXXX
// after
mktemp --tmpdir=/var/tmp fooXXXXXX   // or
mktemp /tmp/fooXXXXXX
Defensive patterns

Strategy: validation

Validate before calling

const isAbsoluteTemplate = (t: string): boolean => path.isAbsolute(t);
if (tmpdirOpt && isAbsoluteTemplate(template)) {
  throw new RangeError(`template '${template}' is absolute; drop --tmpdir or use a bare filename`);
}

Type guard

const canCombineWithTmpdir = (t: string): boolean => !path.isAbsolute(t);

Try / catch

try {
  await Bun.$`mktemp --tmpdir=${dir} ${tmpl}`.quiet();
} catch (e) {
  if (String(e).includes('may not be absolute')) {
    // absolute template already carries its directory
    await Bun.$`mktemp ${tmpl}`.quiet();
  } else throw e;
}

Prevention

When it happens

Trigger: `mktemp --tmpdir=/var/tmp /tmp/fooXXXXXX` — absolute template combined with --tmpdir; scripts that unconditionally add --tmpdir while also passing a templated absolute path from a variable.

Common situations: Wrapper scripts always injecting --tmpdir "$TMPDIR" while callers pass absolute templates; config-driven tmp paths where the template already includes the directory; migration from `mktemp -p` habits.

Related errors


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