flipped-aurora/gin-vue-admin · error
apis 需为JSON数组或逗号分隔字符串
Error message
apis 需为JSON数组或逗号分隔字符串
What it means
parseAPIItems in role_api_batch_assigner.go accepts the `apis` input as either a JSON array of {path,method} objects or a comma-separated string of path:method items. It throws this error when the input is neither — i.e. the parsed value is not a []interface{} array and not a string, so it falls into the default branch. It is a strict input-format validation guard before path+method items are normalized and deduplicated.
Source
Thrown at server/mcp/role_api_batch_assigner.go:182
// 形如 [{"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
}
path, method, err := parseAPIItemString(part)
if err != nil {
return nil, err
}
appendItem(path, method)
}
default:
return nil, errors.New("apis 需为JSON数组或逗号分隔字符串")
}
// 批内去重(按归一化后的 path+method)
seen := make(map[string]struct{}, len(items))
deduped := items[:0]
for _, item := range items {
path, method := normalizePolicy(item.Path, item.Method)
key := method + " " + path
if _, ok := seen[key]; ok {
continue
}
seen[key] = struct{}{}
deduped = append(deduped, item)
}
return deduped, nil
}
// parseAPIItemString 解析"METHOD /path"或"/path"形式的单条API,方法缺省为POSTView on GitHub (pinned to 3136500ef3)
Solutions
- Send apis as a JSON array of {path, method} objects: apis=[{"path":"/user/list","method":"GET"}]
- Or send a comma-separated string of path:method items: apis=/user/list:GET,/user/create:POST
- Check the request content-type / field encoding — ensure the value is not being double-wrapped or coerced into an object by the client serializer
- Add client-side validation that rejects non-array, non-string apis values before submission
Example fix
// before
{ "apis": { "path": "/user/list", "method": "GET" } }
// after
{ "apis": [ { "path": "/user/list", "method": "GET" } ] }
// or
{ "apis": "/user/list:GET" } Defensive patterns
Strategy: validation
Validate before calling
const apis = payload.apis
const isJsonArray = Array.isArray(apis) || (typeof apis === 'string' && apis.trim().startsWith('['))
const isCsv = typeof apis === 'string' && /:?[A-Za-z]+\s*,/.test(apis)
if (!isJsonArray && !isCsv) throw new Error('apis must be a JSON array or comma-separated path:method string') Type guard
function isValidApis(v) {
if (Array.isArray(v)) return v.every(i => i && typeof i.path === 'string' && typeof i.method === 'string')
return typeof v === 'string'
} Try / catch
try {
await assignRoleApis({ apis })
} catch (e) {
if (String(e.message).includes('JSON数组或逗号分隔')) {
console.error('apis format invalid, use [{path,method}] or "path:METHOD,..."', e)
} else { throw e }
} Prevention
- Always send apis as an array of {path, method} objects from typed clients
- Unit-test the request builder to assert the apis shape before send
- Document the two accepted formats in the API client code
When it happens
Trigger: Calling the batch-assign Handle flow with apis as a bare object (e.g. {"path":"/x","method":"GET"} without array wrapping), a number, boolean, or null. Also when the client sends form data or a nested structure instead of a JSON array string like '[{"path":"/a","method":"GET"}]' or 'path1:GET,path2:POST'.
Common situations: Frontend code passing the wrong shape after refactoring (single object instead of array); API consumers omitting the field wrapper when only one API is assigned; hand-rolled curl calls guessing the format; template/generated code sending an object keyed by path.
Related errors
- 单次分配的部门/岗位数量各不能超过 %d 个
- 无法解析API项 %q,期望 "/path" 或 "METHOD /path"
- 未找到 MCP 独立配置文件,请在当前目录、cmd/mcp 目录或通过 -config / GVA_MCP_CONFIG
- 未能自动识别项目根目录,请在 MCP 配置中设置 autocode.root
- go.mod 中未找到 module 定义
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/edcdfa4d784c0b4f.
Report an issue: GitHub.