{"record":{"id":"a7678763e41649de","repo":"agalwood/Motrix","slug":"plugin-engine-version-too-old","errorCode":"PLUGIN_ENGINE_VERSION_TOO_OLD","errorMessage":"Plugin requires host ${required}; running ${hostVersion}","messagePattern":"Plugin requires host (.+?); running (.+?)","errorType":"error_code","errorClass":"PluginEngineVersionTooOld","httpStatus":null,"severity":"error","filePath":"src/core/plugin/manifest/parse.ts","lineNumber":154,"sourceCode":"  } catch (e) {\n    throw new PluginManifestInvalid(\n      'plugin.manifest.invalid',\n      `manifest is not valid JSON: ${(e as Error).message}`\n    )\n  }\n\n  // Step 1: Read engines.motrix BEFORE strict schema validation.\n  const enginesMotrix =\n    typeof parsed === 'object' &&\n    parsed !== null &&\n    'engines' in parsed &&\n    typeof (parsed as { engines: unknown }).engines === 'object' &&\n    (parsed as { engines: { motrix?: unknown } }).engines !== null\n      ? (parsed as { engines: { motrix?: unknown } }).engines.motrix\n      : undefined\n  if (typeof enginesMotrix === 'string') {\n    if (!semverSatisfies(opts.hostVersion, enginesMotrix)) {\n      throw new PluginEngineVersionTooOld(enginesMotrix, opts.hostVersion)\n    }\n  }\n\n  // Step 2: Apply strict schema validation.\n  const result = ManifestSchema.safeParse(parsed)\n  if (!result.success) {\n    throw new PluginManifestInvalid(\n      'plugin.manifest.invalid',\n      'manifest failed schema validation',\n      result.error.issues\n    )\n  }\n\n  // Step 3: Enforce reserved-publisher invariant. Community plugins must not\n  // claim a reserved publisher (motrix.*, verified.*, official.*, system.*).\n  // Built-ins shipped inside the app bundle are exempt — they originate from\n  // <resourcesDir>/builtin-plugins/ and the registry passes origin='builtin'.\n  const origin = opts.origin ?? 'community'","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/plugin/manifest/parse.ts#L136-L172","documentation":"Thrown as PluginEngineVersionTooOld (a distinct error code, NOT PluginManifestInvalid) when the plugin's engines.motrix range is not satisfied by opts.hostVersion. It runs AFTER successful JSON parse but BEFORE Zod schema validation, so a plugin can be rejected for the host being too old even if structurally valid. The message names both the required range and the running host version.","triggerScenarios":"Plugin declares engines.motrix='^3.0.0' and the host is on 2.5.0; plugin requires '>=2.5.0' and host is 2.4.1; semverSatisfies returns false for the host/range pair.","commonSituations":"User on an older Motrix tries a plugin built for a newer API; plugin author set engines too high; host has not been updated.","solutions":["Update Motrix to a version that satisfies the plugin's engines.motrix range.","If you are the author, lower engines.motrix to match the oldest host you support, or backport the API usage.","Before installing, check semverSatisfies(hostVersion, manifest.engines.motrix) and surface a friendly message."],"exampleFix":"// before — plugin requires ^3.0.0, host is 2.5.0\n// manifest.json: { \"engines\": { \"motrix\": \"^3.0.0\" } }\n// after — author widens support to 2.5+\n// { \"engines\": { \"motrix\": \">=2.5.0\" } }","handlingStrategy":"validation","validationCode":"import { semverSatisfies } from './parse'\n// peek engines.motrix from the raw JSON before full parse\nconst peek = JSON.parse(raw)\nconst range = peek?.engines?.motrix\nif(typeof range==='string' && !semverSatisfies(hostVersion, range)){\n  throw new Error(`host ${hostVersion} does not satisfy plugin range ${range}`)\n}","typeGuard":null,"tryCatchPattern":"try { parseManifest(raw, {hostVersion}) }\ncatch(e){ if(e instanceof PluginEngineVersionTooOld){ /* prompt user to update Motrix or pick a compatible plugin */ } else throw e }","preventionTips":["Check semverSatisfies(hostVersion, engines.motrix) before attempting install.","Authors: set engines.motrix to the oldest host you actually support.","Surface the required range and current host version to the user."],"tags":["manifest","engines","semver","host-compat","version-mismatch"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}