{"record":{"id":"8e34b343bce06046","repo":"flipped-aurora/gin-vue-admin","slug":"primarydeptid-deptids","errorCode":null,"errorMessage":"primaryDeptId 需与 deptIds 一起传入(主部门必须属于本次追加或已有的部门集合);仅调整主部门请到前端组织管理页操作","messagePattern":"primaryDeptId 需与 deptIds 一起传入\\(主部门必须属于本次追加或已有的部门集合\\);仅调整主部门请到前端组织管理页操作","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/org_member_assigner.go","lineNumber":98,"sourceCode":"\n\tdeptIDs, err := parseUintList(args[\"deptIds\"], \"deptIds\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpositionIDs, err := parseUintList(args[\"positionIds\"], \"positionIds\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(deptIDs) == 0 && len(positionIDs) == 0 {\n\t\treturn nil, errors.New(\"deptIds 与 positionIds 至少需要传一个\")\n\t}\n\tif len(deptIDs) > orgBatchLimit || len(positionIDs) > orgBatchLimit {\n\t\treturn nil, fmt.Errorf(\"单次分配的部门/岗位数量各不能超过 %d 个\", orgBatchLimit)\n\t}\n\t// primaryDeptId 只在设置部门(deptIds)时生效;仅传 primaryDeptId 不传 deptIds 会被静默丢弃,\n\t// 显式挡回避免调用方误以为主部门已变更\n\tif value, ok := args[\"primaryDeptId\"]; ok && value != nil && len(deptIDs) == 0 {\n\t\treturn nil, errors.New(\"primaryDeptId 需与 deptIds 一起传入(主部门必须属于本次追加或已有的部门集合);仅调整主部门请到前端组织管理页操作\")\n\t}\n\n\t// 校验目标部门/岗位真实存在,把无效ID挡在写入之前\n\tif len(deptIDs) > 0 {\n\t\tdeptIndex, err := fetchDeptIndex(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, id := range deptIDs {\n\t\t\tif _, ok := deptIndex[id]; !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"部门 %d 不存在,可先用 query_org_structure 查询部门树\", id)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, id := range positionIDs {\n\t\tquery := url.Values{}\n\t\tquery.Set(\"id\", strconv.FormatUint(uint64(id), 10))\n\t\tif _, err := getUpstream[system.SysPosition](ctx, \"/position/findPosition\", query); err != nil {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/org_member_assigner.go#L80-L116","documentation":"In org_member_assigner, primaryDeptId is only honored when deptIds is also provided, because the primary department must belong to the department set being assigned (or already assigned). If the caller passes primaryDeptId without deptIds, the tool raises this error explicitly instead of silently dropping the field — the guard exists so callers don't mistakenly believe the primary department changed.","triggerScenarios":"Calling org_member_assigner with a non-null args[\"primaryDeptId\"] while deptIds is absent or empty (e.g. only positionIds given); a payload where deptIds was filtered down to zero entries but primaryDeptId remained.","commonSituations":"Callers wanting to change only a member's primary department via this tool; refactored code that stopped sending deptIds but kept primaryDeptId; template/prompt drift where the primaryDeptId example survived while deptIds was removed.","solutions":["Pass deptIds together with primaryDeptId, ensuring the primary ID is in the current department set","For a primary-department-only change, use the frontend organization management page as the error suggests","Remove primaryDeptId from the payload if you did not intend to change the primary department","Confirm the primaryDeptId value exists and matches one of the deptIds entries"],"exampleFix":"// before\nargs := map[string]interface{}{ \"username\": \"alice\", \"positionIds\": []uint{2}, \"primaryDeptId\": 3 }\n// after\nargs := map[string]interface{}{ \"username\": \"alice\", \"deptIds\": []uint{3}, \"positionIds\": []uint{2}, \"primaryDeptId\": 3 }","handlingStrategy":"validation","validationCode":"func validPrimaryDept(args map[string]interface{}) error {\n  if v, ok := args[\"primaryDeptId\"]; ok && v != nil {\n    d, _ := args[\"deptIds\"].([]interface{})\n    if len(d) == 0 {\n      return fmt.Errorf(\"primaryDeptId requires a non-empty deptIds list\")\n    }\n  }\n  return nil\n}","typeGuard":"func primaryDeptAllowed(args map[string]interface{}) bool {\n  v, present := args[\"primaryDeptId\"]\n  if !present || v == nil {\n    return true\n  }\n  d, _ := args[\"deptIds\"].([]interface{})\n  return len(d) > 0\n}","tryCatchPattern":"if err := validPrimaryDept(args); err != nil {\n  // route primary-only changes to the frontend org management page instead\n  return errRoutingToFrontend\n}","preventionTips":["Never send primaryDeptId without deptIds","Ensure primaryDeptId is a member of the deptIds set","For primary-only adjustments, use the frontend organization management page","Drop nil primaryDeptId keys from generated payloads"],"tags":["mcp","parameter-validation","go","org-management"],"backgroundTag":"invalid-parameter-combination","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}