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", notView on GitHub (pinned to 1a708ee577)
Solutions
- Confirm the callee command is declared with public:true and includes both argsSchema and resultSchema in its manifest.
- Verify the exact commandId spelling against contributes.commands[].id in the callee manifest.
- 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.
- 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
- Only invoke commands declared public:true with both schemas.
- Cross-check commandId spelling against contributes.commands[].id.
- Ensure installCommandSchemas ran and uninstall wasn't called early.
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
- plugin.commands.access_denied
- PluginRuntimeFault
- plugin.commands.id_out_of_namespace
- plugin.command.not_declared_in_manifest
- plugin.commands.not_found
AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12).
Data as JSON: /api/errors/0ba6a51c8ff7c1dd.
Report an issue: GitHub.