siyuan-note/siyuan · error
invalid json schema: %v
Error message
invalid json schema: %v
What it means
Thrown by jsCapabilitySchemaToGoSchema when the JSON-serialized schema fails to unmarshal into the Go tools.ToolSchema struct. The JSON is valid (MarshalJSON succeeded) but its structure does not match the ToolSchema Go type — missing required fields, wrong types, or unknown enum values.
Source
Thrown at kernel/plugin/api_agent.go:270
})))
lo.Must0(ObjectFreeze(rt, agentAPI))
lo.Must0(siyuan.Set("agent", agentAPI))
return
}
// jsCapabilitySchemaToGoSchema 将 JavaScript 能力 Schema 转换为 Go ToolSchema。
func jsCapabilitySchemaToGoSchema(rt *goja.Runtime, value goja.Value) (toolSchema *tools.ToolSchema, err error) {
schemaJson, marshalErr := value.ToObject(rt).MarshalJSON()
if marshalErr != nil {
err = fmt.Errorf("failed to serialize inputSchema: %v", marshalErr)
return
}
schema := &tools.ToolSchema{}
unmarshalErr := json.Unmarshal(schemaJson, schema)
if unmarshalErr != nil {
err = fmt.Errorf("invalid json schema: %v", unmarshalErr)
return
}
toolSchema = schema
return
}
func jsCapabilityEffectsToGoEffects(rt *goja.Runtime, value goja.Value) (*tools.ToolEffects, error) {
effects := &tools.ToolEffects{}
if err := unmarshalCapabilityJSON(rt, value, effects, "effects"); err != nil {
return nil, err
}
return effects, nil
}
func jsCapabilityActionEffectsToGoEffects(rt *goja.Runtime, value goja.Value) (map[string]tools.ToolEffects, error) {
actionEffects := map[string]tools.ToolEffects{}
if err := unmarshalCapabilityJSON(rt, value, &actionEffects, "actionEffects"); err != nil {View on GitHub (pinned to 251596fc0d)
Solutions
- Ensure inputSchema follows standard JSON Schema format with 'type', 'properties', etc.
- Validate the schema against the tools.ToolSchema struct definition in kernel/mcp/tools
- Use a JSON Schema validator library on the JS side before passing the schema
Example fix
// before
await siyuan.agent.registerCapability('myTool', {
description: '...',
inputSchema: ['type', 'object'] // array, not object
}, handler);
// after
await siyuan.agent.registerCapability('myTool', {
description: '...',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string' }
}
}
}, handler); Defensive patterns
Strategy: validation
Validate before calling
// Validate schema is a plain object with expected JSON Schema structure
if (typeof inputSchema !== 'object' || Array.isArray(inputSchema)) {
throw new Error('inputSchema must be a JSON Schema object');
}
if (typeof inputSchema.type !== 'string') {
throw new Error('inputSchema.type must be a string (e.g., "object")');
}
config.inputSchema = inputSchema; Type guard
function isValidJsonSchema(v) {
return v != null && typeof v === 'object'
&& !Array.isArray(v)
&& typeof v.type === 'string';
} Prevention
- Follow standard JSON Schema format for inputSchema and outputSchema
- Reference the tools.ToolSchema Go struct to understand expected fields
When it happens
Trigger: Passing an inputSchema whose JSON structure doesn't match tools.ToolSchema — for example, an array instead of an object, or an object with type: 'invalid' where the Go struct expects a specific set of values.
Common situations: Plugin uses an ad-hoc schema format instead of standard JSON Schema; the schema was hand-written with typos; a version change in the ToolSchema struct introduced new required fields.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- config.inputSchema is required
- registerCapability requires 3 arguments: name, config, handl
- config.description must not be empty
- config.description is required and must be a string
- second argument must be a config object
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/c02e7bae029cd5cb.
Report an issue: GitHub.