agalwood/Motrix · error · AppError

PluginRuntimeFault

PluginRuntimeFault

Error message

plugin.command.not_public

What it means

Thrown by SchemaCache.validateArgs when no compiled validator pair exists for (pluginId, commandId). A pair only exists when the command was public:true AND had BOTH argsSchema and resultSchema compiled at install time; everything else is treated as 'not part of the public surface'. So this means the command is not exposed for cross-plugin invocation at all.

Source

Thrown at src/core/plugin/commands/schema-cache.ts:76

        // on Ajv to throw on malformed input (caught below).
        args = this.ajv.compile(cmd.argsSchema as AnySchema)
        result = this.ajv.compile(cmd.resultSchema as AnySchema)
      } catch (cause) {
        throw new AppError(
          ErrorCode.PluginManifestInvalid,
          `plugin.command.schema_compile_failed: ${cmd.id}`,
          cause instanceof Error ? cause.message : String(cause)
        )
      }
      compiled.set(cmd.id, { args, result })
    }
    this.byPlugin.set(pluginId, compiled)
  }

  validateArgs(pluginId: string, commandId: string, args: unknown): void {
    const pair = this.byPlugin.get(pluginId)?.get(commandId)
    if (!pair) {
      throw new AppError(
        ErrorCode.PluginRuntimeFault,
        'plugin.command.not_public'
      )
    }
    if (!pair.args(args)) {
      throw new AppError(
        ErrorCode.PluginRuntimeFault,
        `plugin.command.args_invalid: ${this.ajv.errorsText(pair.args.errors)}`
      )
    }
  }

  validateResult(pluginId: string, commandId: string, result: unknown): void {
    const pair = this.byPlugin.get(pluginId)?.get(commandId)
    if (!pair) {
      // No validator installed — defensive no-op. CrossPluginInvoker only
      // reaches this branch after a successful validateArgs lookup, so
      // absence here means "no compiled validator for this command", not

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Confirm the callee command is declared with public:true and includes both argsSchema and resultSchema in its manifest.
  2. Verify the exact commandId spelling against contributes.commands[].id in the callee manifest.
  3. If reached from the invoker pipeline, note this is treated as a host bookkeeping problem (not the caller's fault) — the caller is not throttled for it.
  4. Ensure SchemaCache.installCommandSchemas ran for the callee plugin and SchemaCache.uninstall was not prematurely called.

Example fix

// before (callee manifest)
{ id: "acme.f.run", argsSchema: {...}, resultSchema: {...} }

// after
{ id: "acme.f.run", public: true, argsSchema: {...}, resultSchema: {...} }
Defensive patterns

Strategy: validation

Validate before calling

const cmd = callee.manifest.contributes.commands?.find((c) => c.id === commandId)
if (!cmd || cmd.public !== true || !cmd.argsSchema || !cmd.resultSchema) { /* not invokable */ }

Try / catch

try { schemas.validateArgs(pluginId, commandId, args) }
catch (e) { if (e.message === 'plugin.command.not_public') { /* command is private or missing schemas */ } else throw e }

Prevention

When it happens

Trigger: validateArgs is called for a commandId that is private (public missing/false), missing one of its schemas, failed to compile (which would have aborted install), or belongs to a plugin whose schemas were never installed (or were uninstalled).

Common situations: A caller tries to invoke a command the callee never marked public; the callee forgot to ship argsSchema/resultSchema for a public command; the callee was uninstalled mid-flight; or a typo in the commandId resolves to a private command with the same name prefix.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/0ba6a51c8ff7c1dd. Report an issue: GitHub.