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

  1. Use a standard JSON Schema object: {type:"object", properties:{...}, required:[...]}
  2. Ensure "type" and other fields are strings, not numbers or nested objects
  3. Read the wrapped unmarshalErr to see which field failed to decode
  4. 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

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.

Related errors


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)