flipped-aurora/gin-vue-admin · error

deptIds 与 positionIds 至少需要传一个

Error message

deptIds 与 positionIds 至少需要传一个

What it means

The org_member_assigner MCP tool assigns members to departments and/or positions; it requires at least one of the 'deptIds' or 'positionIds' lists. If both parsed lists are empty the tool refuses to proceed rather than performing a no-op write. A secondary limit check follows: each list may contain at most orgBatchLimit entries per call.

Source

Thrown at server/mcp/org_member_assigner.go:90

func (o *OrgMemberAssigner) Handle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	args := request.GetArguments()

	userID, err := parseUintParam(args["userId"], "userId")
	if err != nil {
		return nil, err
	}
	usernameHint, _ := args["username"].(string)

	deptIDs, err := parseUintList(args["deptIds"], "deptIds")
	if err != nil {
		return nil, err
	}
	positionIDs, err := parseUintList(args["positionIds"], "positionIds")
	if err != nil {
		return nil, err
	}
	if len(deptIDs) == 0 && len(positionIDs) == 0 {
		return nil, errors.New("deptIds 与 positionIds 至少需要传一个")
	}
	if len(deptIDs) > orgBatchLimit || len(positionIDs) > orgBatchLimit {
		return nil, fmt.Errorf("单次分配的部门/岗位数量各不能超过 %d 个", orgBatchLimit)
	}
	// primaryDeptId 只在设置部门(deptIds)时生效;仅传 primaryDeptId 不传 deptIds 会被静默丢弃,
	// 显式挡回避免调用方误以为主部门已变更
	if value, ok := args["primaryDeptId"]; ok && value != nil && len(deptIDs) == 0 {
		return nil, errors.New("primaryDeptId 需与 deptIds 一起传入(主部门必须属于本次追加或已有的部门集合);仅调整主部门请到前端组织管理页操作")
	}

	// 校验目标部门/岗位真实存在,把无效ID挡在写入之前
	if len(deptIDs) > 0 {
		deptIndex, err := fetchDeptIndex(ctx)
		if err != nil {
			return nil, err
		}
		for _, id := range deptIDs {
			if _, ok := deptIndex[id]; !ok {

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Include at least one ID in deptIds or positionIds
  2. If you only intended to set the primary department, pass it together with deptIds (or use the frontend org management page for a primary-only change)
  3. Send both parameters as JSON arrays of numeric IDs, not strings or objects
  4. Split very large assignments into multiple calls respecting the orgBatchLimit

Example fix

// before
args := map[string]interface{}{ "username": "alice", "primaryDeptId": 3 }
// after
args := map[string]interface{}{ "username": "alice", "deptIds": []uint{3}, "primaryDeptId": 3 }
Defensive patterns

Strategy: validation

Validate before calling

func validAssignArgs(args map[string]interface{}) error {
  d, _ := args["deptIds"].([]interface{})
  p, _ := args["positionIds"].([]interface{})
  if len(d) == 0 && len(p) == 0 {
    return fmt.Errorf("provide at least one of deptIds or positionIds")
  }
  return nil
}

Type guard

func hasAssignTarget(args map[string]interface{}) bool {
  d, _ := args["deptIds"].([]interface{})
  p, _ := args["positionIds"].([]interface{})
  return len(d) > 0 || len(p) > 0
}

Try / catch

_, err := callTool(ctx, "org_member_assigner", args)
if err != nil && strings.Contains(err.Error(), "至少需要传一个") {
  return fmt.Errorf("assignment skipped: no deptIds/positionIds supplied: %w", err)
}

Prevention

When it happens

Trigger: Calling org_member_assigner with neither deptIds nor positionIds; passing both as empty arrays; passing values that parseUintList rejected so both lists end up empty (e.g. non-array types or all-non-numeric entries); only providing primaryDeptId while omitting deptIds.

Common situations: Scripts that conditionally build one list but never the other; callers assuming primaryDeptId alone changes the primary department (it is explicitly rejected without deptIds); oversized batches that should have been split (see the sibling batch-limit error).

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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