{"record":{"id":"9acd5d1ab578660a","repo":"flipped-aurora/gin-vue-admin","slug":"d-query-org-structure-9acd5d","errorCode":null,"errorMessage":"部门 %d 不存在,可先用 query_org_structure 查询部门树","messagePattern":"部门 (.+?) 不存在,可先用 query_org_structure 查询部门树","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/mcp/role_data_scope_setter.go","lineNumber":107,"sourceCode":"\t}\n\tscope := int(dataScope)\n\n\tvar deptIDs []uint\n\tif scope == 5 {\n\t\tdeptIDs, err = parseUintList(args[\"deptIds\"], \"deptIds\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := requireNonEmptyList(deptIDs, \"deptIds\"); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"档位5(自定义部门)必须指定部门集合: %w\", err)\n\t\t}\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\n\t// 读取变更前状态:角色档位来自角色树,自定义部门集来自专用接口\n\tauthority, err := fetchAuthority(ctx, authorityID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tquery := url.Values{}\n\tquery.Set(\"authorityId\", strconv.FormatUint(uint64(authorityID), 10))\n\tbeforeDeptsResp, err := getUpstream[[]uint](ctx, \"/authority/getDataScopeDepts\", query)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"读取角色当前自定义部门集失败: %w\", err)\n\t}\n\n\tbefore := dataScopeState{\n\t\tDataScope: authority.DataScope,","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/mcp/role_data_scope_setter.go#L89-L125","documentation":"For tier-5 custom scopes each supplied department ID is checked against an index of departments fetched from the upstream server. An ID not present in that index is rejected with a hint to query the org tree via the query_org_structure tool first. This prevents creating scope rows pointing at nonexistent departments.","triggerScenarios":"Calling set-data-scope with dataScope=5 and deptIds containing an ID that does not exist upstream (typo, stale ID, ID from a different environment, or a soft-deleted department).","commonSituations":"Copying dept IDs from a test database into production; department was deleted after the ID was recorded; hardcoding IDs instead of querying query_org_structure.","solutions":["Call the query_org_structure MCP tool to list valid department IDs and replace the invalid one","Check for typos or wrong-environment IDs in deptIds","Verify the department was not soft-deleted in the gva admin UI"],"exampleFix":"// before\ndeptIds := []uint{2, 999}\n// after\n// look up real IDs via query_org_structure first\ndeptIds := []uint{2, 7}","handlingStrategy":"validation","validationCode":"// resolve IDs via query_org_structure before setting scope\ntree, err := queryOrgStructure(ctx)\nif err != nil {\n    return err\n}\nvalid := make(map[uint]struct{})\nfor _, d := range flatten(tree) {\n    valid[d.ID] = struct{}{}\n}\nfor _, id := range deptIds {\n    if _, ok := valid[id]; !ok {\n        return fmt.Errorf(\"dept %d not found\", id)\n    }\n}","typeGuard":"func allDeptsExist(ids []uint, index map[uint]struct{}) bool {\n    for _, id := range ids {\n        if _, ok := index[id]; !ok {\n            return false\n        }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Always query query_org_structure for IDs instead of hardcoding","Re-fetch IDs after environment switches or menu/org re-seeding","Check for soft-deleted departments in the admin UI"],"tags":["mcp","validation","org-structure"],"backgroundTag":"referenced-entity-not-found","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}