flipped-aurora/gin-vue-admin · error

apis 数组元素需为 {path,method} 对象或 "METHOD /path" 字符串

Error message

apis 数组元素需为 {path,method} 对象或 "METHOD /path" 字符串

What it means

parseAPIItems accepts only two element shapes: an object with path/method fields, or a "METHOD /path" string parseable by parseAPIItemString. The error is thrown when an element is any other JSON type (number, bool, null, nested array), i.e. the default branch of the type switch.

Source

Thrown at server/mcp/role_api_batch_assigner.go:155

	switch value := v.(type) {
	case []any:
		for _, entry := range value {
			switch typed := entry.(type) {
			case map[string]any:
				path, _ := typed["path"].(string)
				if strings.TrimSpace(path) == "" {
					return nil, errors.New("apis 数组元素缺少 path 字段")
				}
				method, _ := typed["method"].(string)
				appendItem(path, method)
			case string:
				path, method, err := parseAPIItemString(typed)
				if err != nil {
					return nil, err
				}
				appendItem(path, method)
			default:
				return nil, errors.New("apis 数组元素需为 {path,method} 对象或 \"METHOD /path\" 字符串")
			}
		}
	case string:
		trimmed := strings.TrimSpace(value)
		if trimmed == "" {
			return nil, nil
		}
		// 兼容只支持字符串参数的 MCP 客户端把 JSON 数组序列化成字符串传入的情况:
		// 形如 [{"path":..,"method":..}] 若按逗号切分会碎成垃圾策略,先尝试按 JSON 数组解析
		if strings.HasPrefix(trimmed, "[") {
			var arr []any
			if err := json.Unmarshal([]byte(trimmed), &arr); err == nil {
				return parseAPIItems(arr)
			}
		}
		for part := range strings.SplitSeq(trimmed, ",") {
			if strings.TrimSpace(part) == "" {
				continue

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Format each element as {"path":"/x","method":"GET"} or "GET /x"
  2. Remove or fix elements of the wrong type (numbers/bools/null/nested arrays)
  3. Run a client-side type check that rejects items not string-or-object

Example fix

// before
args["apis"] = []any{[]any{"GET", "/api/user/list"}}
// after
args["apis"] = []any{"GET /api/user/list"}
Defensive patterns

Strategy: type-guard

Validate before calling

const ok = apis.every(a =>
  typeof a === "string" ||
  (typeof a === "object" && a !== null && !Array.isArray(a))
)
if (!ok) throw new Error("apis 元素类型不合法")

Type guard

function isStringOrApiObj(v: unknown): boolean {
  if (typeof v === "string") return true
  return typeof v === "object" && v !== null && !Array.isArray(v)
}

Try / catch

try {
  await callTool("role_api_batch_assigner", { apis })
} catch (e) {
  if (String(e.message).includes("需为 {path,method} 对象或")) {
    // 重新格式化字符串元素,例如 "GET /path"
  }
  throw e
}

Prevention

When it happens

Trigger: An apis element like 42, true, null, or ["/api/x"] — anything that is neither map[string]any nor string.

Common situations: Caller sending a bare path "/api/user/list" as a nested array element, string-encoded JSON that arrives still as an array, or items pasted from a loose schema.

Related errors


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