flipped-aurora/gin-vue-admin · error

序列化 tool schema 失败: %w

Error message

序列化 tool schema 失败: %w

What it means

In manifestCommandToTool (server/mcp/dynamic_schema.go:65), the CLI manifest command's parameter definitions are converted into a JSON Schema map which is serialized with json.Marshal before being registered as an MCP tool. If marshaling fails, the tool cannot be registered and this error wraps the underlying json error. In practice the schema is built from simple maps/strings/bools, so this is nearly impossible to hit unless a parameter name or description carries unsupported data.

Source

Thrown at server/mcp/dynamic_schema.go:65

			prop["items"] = map[string]any{"type": arrayItemJSONType(p.Type)}
		}
		properties[p.Name] = prop
		if p.Required {
			required = append(required, p.Name)
		}
	}

	schema := map[string]any{
		"type":       "object",
		"properties": properties,
	}
	if len(required) > 0 {
		schema["required"] = required
	}

	rawSchema, err := json.Marshal(schema)
	if err != nil {
		return mcp.Tool{}, fmt.Errorf("序列化 tool schema 失败: %w", err)
	}

	description := cmd.Description
	if description == "" {
		description = cmd.Summary
	}
	if description == "" {
		description = fmt.Sprintf("%s %s", strings.ToUpper(cmd.Method), cmd.Path)
	}

	tool := mcp.NewToolWithRawSchema(cmd.Name, description, rawSchema)
	return tool, nil
}

// manifestTypeToJSONType 把 CLI manifest 的参数类型映射到 JSON Schema 类型。
func manifestTypeToJSONType(t string) string {
	switch strings.ToLower(strings.TrimSpace(t)) {
	case "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "integer":

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Check the wrapped %w error to identify which value failed to marshal; json.Marshal errors name the unsupported type.
  2. Inspect the manifest command's Parameters (names, descriptions, types) for invalid or unexpected data and fix the manifest source.
  3. Verify no recent code change inserted non-JSON-serializable values (func, channel, cycle) into the schema map in manifestCommandToTool.
  4. If a single command is bad, fix or remove it so registerDynamicTools can register the remaining tools.

Example fix

// before: schema built with possibly non-serializable value
properties[p.Name] = prop
// after: sanitize fields to plain strings before building the map
prop := map[string]any{
	"type":        jsonType,
	"description": fmt.Sprintf("%v", p.Description),
}
Defensive patterns

Strategy: validation

Validate before calling

// before registering, sanity-check the manifest command
func validManifestCommand(cmd autoRes.SysCliManifestCommand) bool {
	if cmd.Name == "" || cmd.Path == "" || cmd.Method == "" {
		return false
	}
	for _, p := range cmd.Parameters {
		if p.Name == "" || p.Field == "" {
			return false
		}
	}
	return true
}

Type guard

func isJSONSerializable(v any) bool {
	_, err := json.Marshal(v)
	return err == nil
}

Try / catch

tool, err := manifestCommandToTool(cmd)
if err != nil {
	logger.Warn("skip unregistrable command %s: %v", cmd.Name, err)
	continue
}

Prevention

When it happens

Trigger: Calling registerDynamicTools during MCP server startup when a manifest command (autoRes.SysCliManifestCommand) produces a schema map that json.Marshal cannot serialize — e.g. a parameter Name/Description containing invalid state, or a future change introducing a non-serializable value (channel, func, cyclic map) into properties/required.

Common situations: Custom or hand-edited CLI manifest files with exotic field content; code modifications adding dynamic values (e.g. funcs) to the schema map; corrupted manifest data loaded from the CLI pipeline.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/8cf948b1097c4872. Report an issue: GitHub.