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) == "" {
continueView on GitHub (pinned to 3136500ef3)
Solutions
- Format each element as {"path":"/x","method":"GET"} or "GET /x"
- Remove or fix elements of the wrong type (numbers/bools/null/nested arrays)
- 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
- Emit canonical {path,method} objects client-side only; avoid heterogeneous items like strings and numbers
- Parse JSON with a parser that preserves types
- Always validate array element types before submit, not just the array itself
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.