siyuan-note/siyuan · error
invalid json schema
Error message
invalid json schema: %v
What it means
After the JS inputSchema is serialized to JSON, it is unmarshalled into tools.ToolSchema. If the JSON does not match the Go struct's expected field types (json.Unmarshal fails), this error is returned. It means the schema object exists and serializes, but its contents are not a valid ToolSchema for the agent tool system.
Solutions
- Use a standard JSON Schema object: {type:"object", properties:{...}, required:[...]}
- Ensure "type" and other fields are strings, not numbers or nested objects
- Read the wrapped unmarshalErr to see which field failed to decode
- Validate the schema with a JSON Schema validator in the plugin before registering
Example fix
// before
inputSchema: { type: 1, properties: [] }
// after
inputSchema: { type: "object", properties: { q: { type: "string" } }, required: ["q"] } Defensive patterns
Strategy: validation
Validate before calling
function validateSchema(s) {
if (typeof s !== "object" || s === null || Array.isArray(s)) return false;
if (typeof s.type !== "string") return false;
if (s.properties && typeof s.properties !== "object") return false;
if (s.required && !Array.isArray(s.required)) return false;
return true;
} Type guard
const isJsonSchemaObject = (v) => v !== null && typeof v === "object" && !Array.isArray(v) && typeof v.type === "string";
Prevention
- Keep "type" a string ("object", "string", "number"...)
- Validate the schema with ajv or a JSON Schema validator before registering
- Compare against the tool registration docs / sample plugin
When it happens
Trigger: A plugin passes an inputSchema whose fields have wrong types, e.g. inputSchema: "a string", inputSchema: [], inputSchema: {type: 123}, or properties values that do not decode into the expected ToolSchema field types.
Common situations: Authors copy an OpenAPI-style or vendor-specific schema instead of the expected JSON Schema shape; typos like "typ":"object" leave wrong-typed fields; passing a top-level array of properties instead of an object.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to serialize config.
- failed to serialize inputSchema
- globalThis.siyuan.plugin.lifecycle is not an object
- globalThis.siyuan.plugin.lifecycle not found
- globalThis.siyuan.plugin.lifecycle.
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/c02e7bae029cd5cb.
Report an issue: GitHub.
Appendix: 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 9f775e8a12)