jackwener/OpenCLI · error · Error

target appeared during reservation

Error message

target appeared during reservation

What it means

reserveAudioFile in clis/minimax/utils.js reserves a unique timestamped output path for generated MiniMax music using a write-exclusive lock file. After acquiring the lock it re-checks the target; if the target file appeared between the first existence check and lock acquisition, it releases the lock and throws 'target appeared during reservation', wrapped as CommandExecutionError 'MiniMax music cannot reserve output file <target>: ...'. This is a deliberate TOCTOU guard ensuring the same-second output file is never silently overwritten.

Source

Thrown at clis/minimax/utils.js:192

    if (raw.startsWith('~/')) return path.join(os.homedir(), raw.slice(2));
    if (raw.startsWith('~')) throw new ArgumentError(`Unsupported home-directory path: ${raw}`);
    return path.resolve(raw);
}

export function reserveAudioFile(dir, model, format, now = new Date()) {
    const stamp = now.toISOString().replace(/[-:]/g, '').replace(/\.\d+Z$/, 'Z');
    const target = path.join(dir, `${model}-${stamp}.${format}`);
    const lock = `${target}.lock`;
    const staging = `${target}.${process.pid}.${randomUUID()}.tmp`;
    try {
        fs.mkdirSync(dir, { recursive: true });
        if (!fs.statSync(dir).isDirectory()) throw new Error('not a directory');
        fs.accessSync(dir, fs.constants.W_OK);
        if (fs.existsSync(target)) throw new Error('target already exists');
        fs.writeFileSync(lock, String(process.pid), { flag: 'wx', mode: 0o600 });
        if (fs.existsSync(target)) {
            fs.rmSync(lock, { force: true });
            throw new Error('target appeared during reservation');
        }
        return { target, lock, staging };
    } catch (error) {
        throw new CommandExecutionError(`MiniMax music cannot reserve output file ${target}: ${error?.message ?? error}`);
    }
}

export function commitAudioFile(reservation, bytes) {
    try {
        fs.writeFileSync(reservation.staging, bytes, { flag: 'wx', mode: 0o600 });
        // A same-filesystem hard link publishes the complete staging inode and
        // fails if target already exists on POSIX and Windows alike.
        fs.linkSync(reservation.staging, reservation.target);
        cleanupAudioFile(reservation);
        return reservation.target;
    } catch (error) {
        cleanupAudioFile(reservation);
        throw new CommandExecutionError(`MiniMax music could not atomically write ${reservation.target}: ${error?.message ?? error}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Rerun the command — the timestamp advances, producing a different filename and resolving the collision.
  2. Use a distinct --output directory per concurrent job to eliminate collisions.
  3. Serialize concurrent music generations (flock, job queue) so only one reserves a file at a time.
  4. If the collision persists, remove or rename the target file at that path and retry.

Example fix

// before (collides when run in parallel)
minimax music --prompt 'lofi' --output ./out &
minimax music --prompt 'lofi' --output ./out &

// after (per-job output dir avoids same-second collision)
minimax music --prompt 'lofi' --output ./out/job-$$_$(date +%s%N)
Defensive patterns

Strategy: try-catch

Validate before calling

const target = path.join(dir, `${model}-${stamp}.${format}`);
if (fs.existsSync(target)) throw new Error(`output already exists: ${target}`);
fs.accessSync(dir, fs.constants.W_OK);

Try / catch

try {
  const reservation = reserveAudioFile(dir, model, format);
  // ... generate and commit
} catch (e) {
  if (String(e.message).includes('target appeared during reservation')) {
    // concurrent run won the race: retry with a fresh timestamp or another dir
  } else { throw e; }
}

Prevention

When it happens

Trigger: A concurrent MiniMax music command created a file at the identical timestamped path `${model}-${stamp}.${format}` between the first fs.existsSync(target) check and the post-lock re-check — e.g. two music generations started in the same second writing to the same --output directory.

Common situations: Running two CLI music generation commands in parallel (scripts, CI, cron) sharing an output directory; same-second filename collisions since the name has only second-level precision; retry loops launching two invocations nearly simultaneously.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/9b4f4f33bda6f53b. Report an issue: GitHub.