{"record":{"id":"424d2b1befb75ca1","repo":"agalwood/Motrix","slug":"pluginmanifestinvalid","errorCode":"PluginManifestInvalid","errorMessage":"plugin.command.schema_compile_failed: ${cmd.id}","messagePattern":"plugin\\.command\\.schema_compile_failed: (.+?)","errorType":"exception","errorClass":"AppError","httpStatus":null,"severity":"error","filePath":"src/core/plugin/commands/schema-cache.ts","lineNumber":62,"sourceCode":"    const compiled = new Map<string, CompiledPair>()\n    for (const cmd of cmds) {\n      if (\n        cmd.public !== true ||\n        cmd.argsSchema === undefined ||\n        cmd.resultSchema === undefined\n      ) {\n        continue\n      }\n      let args: ValidateFunction\n      let result: ValidateFunction\n      try {\n        // Ajv typings demand AnySchema; the manifest layer passes us raw\n        // JSON which we have not yet validated, so we widen here and rely\n        // on Ajv to throw on malformed input (caught below).\n        args = this.ajv.compile(cmd.argsSchema as AnySchema)\n        result = this.ajv.compile(cmd.resultSchema as AnySchema)\n      } catch (cause) {\n        throw new AppError(\n          ErrorCode.PluginManifestInvalid,\n          `plugin.command.schema_compile_failed: ${cmd.id}`,\n          cause instanceof Error ? cause.message : String(cause)\n        )\n      }\n      compiled.set(cmd.id, { args, result })\n    }\n    this.byPlugin.set(pluginId, compiled)\n  }\n\n  validateArgs(pluginId: string, commandId: string, args: unknown): void {\n    const pair = this.byPlugin.get(pluginId)?.get(commandId)\n    if (!pair) {\n      throw new AppError(\n        ErrorCode.PluginRuntimeFault,\n        'plugin.command.not_public'\n      )\n    }","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/plugin/commands/schema-cache.ts#L44-L80","documentation":"Thrown at plugin install time by SchemaCache.installCommandSchemas when Ajv.compile throws on a command's argsSchema or resultSchema. The host compiles both schemas for every public command before the plugin is usable, so a malformed JSON Schema aborts installation with ErrorCode.PluginManifestInvalid. The original Ajv message is attached as the third AppError argument for diagnosis.","triggerScenarios":"A public command (public:true) whose argsSchema or resultSchema is not a valid JSON Schema digestible by Ajv in strict mode — e.g. a $ref that resolves nowhere, an unknown keyword under strict:true, a schema that is not an object (bare string used incorrectly), or a draft-incompatible construct.","commonSituations":"Hand-written manifests with typos in keywords (\"typee\":\"string\"), schemas copy-pasted from a different JSON-Schema draft, use of ajv-keywords/formats without registering them, or $ref targets that were renamed. Ajv strict mode (set on the cache at schema-cache.ts:33-37) also rejects many schemas that other validators accept.","solutions":["Read the attached cause message (third AppError arg) — Ajv names the offending keyword and path.","Validate the schema against a JSON-Schema meta-schema or ajv.compile it in isolation during development to catch the error before install.","Align the schema with JSON-Schema draft-07 (the Ajv default) and avoid keywords Ajv strict mode flags.","If the command should not be host-validated, set public:false (or omit it) so it is skipped — but then it cannot be invoked cross-plugin."],"exampleFix":"// before\n{ id: \"acme.f.run\", public: true,\n  argsSchema: { typee: \"object\" },\n  resultSchema: { type: \"object\" } }\n\n// after\n{ id: \"acme.f.run\", public: true,\n  argsSchema: { type: \"object\", properties: {} },\n  resultSchema: { type: \"object\", properties: {} } }","handlingStrategy":"validation","validationCode":"import Ajv from 'ajv'\nconst ajv = new Ajv({ strict: true, useDefaults: false })\nfunction schemaCompiles(s: unknown): boolean { try { ajv.compile(s as any); return true } catch { return false } }","typeGuard":null,"tryCatchPattern":"try { schemaCache.installCommandSchemas(pluginId, cmds) }\ncatch (e) { if (e.message.startsWith('plugin.command.schema_compile_failed')) { /* fix schema from e cause text */ } else throw e }","preventionTips":["Validate every manifest schema with ajv.compile in CI before publish.","Use JSON-Schema draft-07 compatible keywords only.","Read the attached cause message to find the offending keyword/path."],"tags":["plugin","schema","ajv","manifest"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}