agalwood/Motrix · critical · AppError
EngineStartFailed
EngineStartFailed
Error message
Unrecognized aria2 version output from ${binaryPath} What it means
Thrown as an AppError (code EngineStartFailed) by Aria2ProcessManager.probe when running `aria2c --version` produces output that does not match the regex /aria2 version (\S+)/. The probe runs execForOutput(binaryPath, ['--version']) and passes the stdout to parseVersionOutput, which returns null if the version line is absent. This blocks engine startup because feature detection depends on parsing the version and enabled-features list.
Source
Thrown at src/core/engine/aria2/aria2-process-manager.ts:74
export class Aria2ProcessManager {
private process: ChildProcess | null = null
private running = false
private readonly ownershipFilePath: string | null
private readonly inspector: Aria2ProcessInspector
onExit: ((code: number | null, signal: string | null) => void) | null = null
onError: ((err: Error) => void) | null = null
constructor(options: Aria2ProcessManagerOptions = {}) {
this.ownershipFilePath = options.ownershipFilePath ?? null
this.inspector = options.inspector ?? new Aria2ProcessInspector()
}
async probe(binaryPath: string): Promise<EngineFeatureReport> {
const versionOutput = await this.execForOutput(binaryPath, ['--version'])
const report = this.parseVersionOutput(versionOutput)
if (!report) {
throw new AppError(
ErrorCode.EngineStartFailed,
`Unrecognized aria2 version output from ${binaryPath}`
)
}
return report
}
private execForOutput(binaryPath: string, args: string[]): Promise<string> {
return new Promise((resolve, reject) => {
execFile(binaryPath, args, (err, stdout) => {
if (err) {
reject(
new AppError(
ErrorCode.EngineStartFailed,
`Failed to probe aria2 binary at ${binaryPath}: ${err.message}`,
err
)
)View on GitHub (pinned to 1a708ee577)
Solutions
- Run `<binaryPath> --version` manually in a terminal and confirm it prints 'aria2 version X.Y.Z'
- Verify the binary is the correct architecture and platform (file <binaryPath>)
- Check for missing shared libraries: ldd <binaryPath> (Linux) or otool -L (macOS)
- Re-download or reinstall the correct aria2 binary (preferably the Motrix fork)
- Ensure binaryPath is an absolute path to the real executable, not a wrapper or alias
Defensive patterns
Strategy: validation
Validate before calling
import { access, constants } from 'fs/promises'
async function verifyAria2Binary(binaryPath: string): Promise<void> {
await access(binaryPath, constants.X_OK)
// Optionally pre-check --version output format
}
// Before probe:
await verifyAria2Binary(binaryPath) Try / catch
try {
return await processManager.probe(binaryPath)
} catch (e) {
if (e instanceof AppError && e.code === ErrorCode.EngineStartFailed) {
// Binary is wrong/corrupt — re-download or re-resolve the path
await downloadAria2Binary()
return await processManager.probe(resolvedPath)
}
throw e
} Prevention
- Verify the binary exists and is executable before calling probe()
- Run `<binaryPath> --version` in a terminal to confirm it prints 'aria2 version X.Y.Z'
- Ensure the binary matches the host platform/architecture (check with `file <binaryPath>`)
- Use absolute paths to avoid PATH resolution issues with wrapper scripts
When it happens
Trigger: probe(binaryPath) is called; aria2c --version executes but its stdout does not contain the string 'aria2 version <token>' — e.g. the binary prints a help message, an error, a different format, or empty output.
Common situations: binaryPath points to the wrong executable (e.g. a shell script, a different program named aria2c); the aria2 binary is corrupted or for a different platform (e.g. macOS binary on Linux); a very old or heavily patched aria2 fork that changed the --version output format; the binary requires a shared library that is missing and it exits with an error to stderr instead of stdout; PATH resolves to a wrapper script.
Related errors
- EngineProtocolError
- EngineProcessOwnershipUnverified
- EngineProcessTerminationFailed
- aria2 addTorrent gid must contain exactly 16 hexadecimal cha
- aria2 returned gid ${actualGid} instead of reserved gid ${re
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/e46e0f52092438b2.
Report an issue: GitHub.