jackwener/OpenCLI · error · ArgumentError

Unsupported home-directory path: ${raw}

Error message

Unsupported home-directory path: ${raw}

What it means

resolveOutputDir expands a user-supplied output directory value, accepting '~' or '~/...' forms that map to the OS home directory. A bare '~'-prefixed path like '~user/music' or '~foo' is not supported, so the library throws ArgumentError to refuse ambiguous home-directory syntax rather than guessing the target.

Source

Thrown at clis/minimax/utils.js:175

        throw new CommandExecutionError('MiniMax music returned bytes that are not a WAV file');
    }
    if (format === 'mp3' && !isMp3(bytes)) {
        throw new CommandExecutionError('MiniMax music returned bytes that are not an MP3 file');
    }
    return bytes;
}

function isMp3(bytes) {
    return bytes.length >= 3 && bytes.subarray(0, 3).toString('ascii') === 'ID3'
        || bytes.length >= 2 && bytes[0] === 0xff && (bytes[1] & 0xe0) === 0xe0;
}

export function resolveOutputDir(value) {
    const raw = String(value ?? '').trim();
    if (!raw) return path.join(os.homedir(), 'Music', 'minimax');
    if (raw === '~') return os.homedir();
    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');
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Replace the value with an absolute path, e.g. /home/otheruser/Music or /Users/me/Music
  2. Use '~' or '~/...' forms only, which the library expands via os.homedir()
  3. Set an env var or CLI flag with the resolved absolute path instead of relying on shell expansion
  4. If you need ~user expansion, resolve it in your own code (e.g. via getpwnam/passwd lookup) before passing it in

Example fix

// before
resolveOutputDir('~music');            // throws ArgumentError
// after
resolveOutputDir(path.join(os.homedir(), 'Music'));
// or
resolveOutputDir('~/Music');
Defensive patterns

Strategy: validation

Validate before calling

function isValidOutputDir(value) {
    const raw = String(value ?? '').trim();
    if (!raw) return true;                 // falls back to default
    if (raw === '~' || raw.startsWith('~/')) return true;
    if (raw.startsWith('~')) return false; // would throw ArgumentError
    return true;
}
// if (!isValidOutputDir(cfg.outputDir)) cfg.outputDir = cfg.outputDir.replace(/^~[^/]*/, os.homedir());

Try / catch

try {
    const dir = resolveOutputDir(opts.outputDir);
} catch (e) {
    if (e instanceof ArgumentError && String(e.message).includes('Unsupported home-directory path')) {
        const dir = resolveOutputDir(opts.outputDir.replace(/^~(?![/])/, os.homedir() + '/'));
    } else throw e;
}

Prevention

When it happens

Trigger: Passing an output-directory option whose trimmed string starts with '~' but is neither exactly '~' nor starts with '~/': e.g. '~user', '~music', '~/', wait — '~/' matches the handled case, so effectively '~name' style paths.

Common situations: Users copying shell-idiom paths like '~otheruser/Music' into CLI config/env; typos where '~/' was written as '~'; docs showing '~name' expansion that Node's os.homedir() cannot resolve.

Related errors


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