{"record":{"id":"e46e0f52092438b2","repo":"agalwood/Motrix","slug":"enginestartfailed","errorCode":"EngineStartFailed","errorMessage":"Unrecognized aria2 version output from ${binaryPath}","messagePattern":"Unrecognized aria2 version output from (.+?)","errorType":"error_code","errorClass":"AppError","httpStatus":null,"severity":"critical","filePath":"src/core/engine/aria2/aria2-process-manager.ts","lineNumber":74,"sourceCode":"export class Aria2ProcessManager {\n  private process: ChildProcess | null = null\n  private running = false\n  private readonly ownershipFilePath: string | null\n  private readonly inspector: Aria2ProcessInspector\n\n  onExit: ((code: number | null, signal: string | null) => void) | null = null\n  onError: ((err: Error) => void) | null = null\n\n  constructor(options: Aria2ProcessManagerOptions = {}) {\n    this.ownershipFilePath = options.ownershipFilePath ?? null\n    this.inspector = options.inspector ?? new Aria2ProcessInspector()\n  }\n\n  async probe(binaryPath: string): Promise<EngineFeatureReport> {\n    const versionOutput = await this.execForOutput(binaryPath, ['--version'])\n    const report = this.parseVersionOutput(versionOutput)\n    if (!report) {\n      throw new AppError(\n        ErrorCode.EngineStartFailed,\n        `Unrecognized aria2 version output from ${binaryPath}`\n      )\n    }\n    return report\n  }\n\n  private execForOutput(binaryPath: string, args: string[]): Promise<string> {\n    return new Promise((resolve, reject) => {\n      execFile(binaryPath, args, (err, stdout) => {\n        if (err) {\n          reject(\n            new AppError(\n              ErrorCode.EngineStartFailed,\n              `Failed to probe aria2 binary at ${binaryPath}: ${err.message}`,\n              err\n            )\n          )","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/engine/aria2/aria2-process-manager.ts#L56-L92","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { access, constants } from 'fs/promises'\nasync function verifyAria2Binary(binaryPath: string): Promise<void> {\n  await access(binaryPath, constants.X_OK)\n  // Optionally pre-check --version output format\n}\n// Before probe:\nawait verifyAria2Binary(binaryPath)","typeGuard":null,"tryCatchPattern":"try {\n  return await processManager.probe(binaryPath)\n} catch (e) {\n  if (e instanceof AppError && e.code === ErrorCode.EngineStartFailed) {\n    // Binary is wrong/corrupt — re-download or re-resolve the path\n    await downloadAria2Binary()\n    return await processManager.probe(resolvedPath)\n  }\n  throw e\n}","preventionTips":["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"],"tags":["aria2","engine","binary","version","startup"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}