Mintplex-Labs/anything-llm · error · Error
FFMPEG candidate path not found.
Error message
FFMPEG candidate path not found.
What it means
Thrown (and immediately caught/logged) by FFMPEGWrapper.ffmpegPath() when `which ffmpeg`/`where ffmpeg` returns output but the first newline-split line is empty after trimming. Because the throw sits inside a try/catch, the message is only logged; the caller always receives the downstream "FFMPEG binary not found." error instead. It is an internal diagnostic, not a propagated exception.
Source
Thrown at collector/utils/WhisperProviders/ffmpeg/index.js:41
console.log(`\x1b[35m[FFMPEG]\x1b[0m ${text}`, ...args);
}
/**
* Locates ffmpeg binary.
* Uses fix-path on non-Windows platforms to ensure we can find ffmpeg.
*
* @returns {Promise<string>} Path to ffmpeg binary
* @throws {Error}
*/
async ffmpegPath() {
if (this._ffmpegPath) return this._ffmpegPath;
await patchShellEnvironmentPath();
try {
const which = process.platform === "win32" ? "where" : "which";
const result = execSync(`${which} ffmpeg`, { encoding: "utf8" }).trim();
const candidatePath = result?.split("\n")?.[0]?.trim();
if (!candidatePath) throw new Error("FFMPEG candidate path not found.");
if (!this.isValidFFMPEG(candidatePath))
throw new Error("FFMPEG candidate path is not valid ffmpeg binary.");
this.log(`Found FFMPEG binary at ${candidatePath}`);
this._ffmpegPath = candidatePath;
return this._ffmpegPath;
} catch (error) {
this.log(error.message);
}
throw new Error("FFMPEG binary not found.");
}
/**
* Validates that path points to a valid ffmpeg binary.
* Runs ffmpeg -version command.
*
* @param {string} pathToTest - Path of ffmpeg binaryView on GitHub (pinned to 526360e320)
Solutions
- Install ffmpeg and confirm `which ffmpeg` prints a real path in the same shell the Node process uses.
- If Node is GUI-launched, ensure PATH includes /opt/homebrew/bin and /usr/local/bin (patchShellEnvironmentPath already attempts this).
- Set an explicit PATH or FFMPEG location in the process environment before invoking Whisper.
Example fix
// before
const result = execSync(`${which} ffmpeg`, { encoding: "utf8" }).trim();
const candidatePath = result?.split("\n")?.[0]?.trim();
// after — fall back to a known binary location
let candidatePath = result?.split("\n")?.[0]?.trim();
if (!candidatePath && fs.existsSync("/usr/local/bin/ffmpeg")) {
candidatePath = "/usr/local/bin/ffmpeg";
} Defensive patterns
Strategy: validation
Validate before calling
const { execSync } = require("child_process");
function ffmpegOnPath() {
try {
const out = execSync(`${process.platform === "win32" ? "where" : "which"} ffmpeg`, {
encoding: "utf8", stdio: "pipe"
}).trim();
return out.split("\n")[0].trim().length > 0;
} catch { return false; }
}
// before enabling Whisper: if (!ffmpegOnPath()) warn user; Try / catch
try {
const p = await ffmpeg.ffmpegPath();
} catch (e) {
// 20 is swallowed; caller sees error 22 "FFMPEG binary not found."
if (e.message === "FFMPEG binary not found.") { /* guide install */ }
throw e;
} Prevention
- Install ffmpeg before enabling local Whisper transcription.
- Launch Node from a login shell so PATH includes the binary directory.
- Verify with `which ffmpeg` in the exact environment the app runs in.
When it happens
Trigger: `execSync(`${which} ffmpeg`)` returns only whitespace/newlines, so `result.split("\n")[0].trim()` yields an empty string and the `if (!candidatePath)` guard fires.
Common situations: A shell alias/function named ffmpeg that echoes nothing; a broken PATH entry that `which` resolves but prints blank; rare edge where `which` emits a bare newline; tampered PATH in a container.
Related errors
- FFMPEG binary not found.
- FFMPEG candidate path is not valid ffmpeg binary.
- Input file ${inputPath} does not exist.
- FFMPEG conversion failed
- Audio conversion failed.
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/6579725735a3d24a.
Report an issue: GitHub.