{"record":{"id":"f25cfd61547563f1","repo":"gitlabhq/gitlabhq","slug":"no-more-than-max-source-types-source-work-item","errorCode":null,"errorMessage":"No more than %{max_source_types} source work item types can be provided at a time.","messagePattern":"No more than %(.+?) source work item types can be provided at a time\\.","errorType":"validation","errorClass":"Gitlab::Graphql::Errors::ArgumentError","httpStatus":null,"severity":"error","filePath":"app/graphql/resolvers/work_items/move_targets_resolver.rb","lineNumber":40,"sourceCode":"\n      authorize :read_namespace\n\n      MAX_SOURCE_TYPES = 50\n\n      argument :source_full_path, GraphQL::Types::String,\n        required: true,\n        description: 'Full path of the source namespace. For example, `gitlab-org/gitlab-foss`.'\n\n      argument :source_type_ids, [::Types::GlobalIDType[::WorkItems::Type]],\n        required: true,\n        description: <<~DESC.squish\n          Global IDs of the source work item types to compute move targets for.\n          A maximum of #{MAX_SOURCE_TYPES} IDs can be provided.\n        DESC\n\n      def ready?(**args)\n        if args[:source_type_ids].size > MAX_SOURCE_TYPES\n          raise Gitlab::Graphql::Errors::ArgumentError,\n            format(\n              _('No more than %{max_source_types} source work item types can be provided at a time.'),\n              max_source_types: MAX_SOURCE_TYPES\n            )\n        end\n\n        super\n      end\n\n      def resolve(source_full_path:, source_type_ids:)\n        source_namespace = authorized_find!(full_path: source_full_path)\n\n        ::WorkItems::Types::MoveTargetsService.new(\n          current_user: current_user,\n          source_namespace: source_namespace,\n          target_namespace: object,\n          source_type_ids: source_type_ids.map(&:model_id)\n        ).execute","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/gitlabhq/gitlabhq/blob/55ee20384a1f55cb0e362dee1d07149613b1b9bf/app/graphql/resolvers/work_items/move_targets_resolver.rb#L22-L58","documentation":"The `workItemTypesMoveTargets` resolver computes which target types a work item can move to, taking a required `sourceTypeIds` list capped at MAX_SOURCE_TYPES = 50. `ready?` raises ArgumentError (message interpolates the limit) when more than 50 source type global IDs are provided. The cap bounds the per-type move-target computation.","triggerScenarios":"`workItemTypesMoveTargets(sourceFullPath: \"gitlab-org/gitlab\", sourceTypeIds: [51+ gids])`; clients that always send the complete list of type IDs fetched from `workItemTypes` for a large custom hierarchy instead of the subset in use.","commonSituations":"Self-managed instances with many custom work item types; admin tools that mirror every type into every request; code that fetched the full type list once and passes it wholesale without slicing.","solutions":["Send only the source type IDs you actually render (usually one or a handful), not the full catalog","If genuinely needed, batch into groups of at most 50 IDs and merge results","Cache the type list and intersect with what the UI offers before querying"],"exampleFix":"# before\nconst allTypeIds = (await client.request(WORK_ITEM_TYPES)).workItemTypes.nodes.map(n => n.id);\nclient.request(MOVE_TARGETS, { sourceFullPath, sourceTypeIds: allTypeIds }); // 67 ids -> error\n\n# after\nconst needed = pickRelevantTypes(allTypeIds, selection);\nclient.request(MOVE_TARGETS, { sourceFullPath, sourceTypeIds: needed.slice(0, 50) });","handlingStrategy":"validation","validationCode":"const MAX_SOURCE_TYPES = 50;\nfunction assertSourceTypeIds(ids) {\n  if (!Array.isArray(ids) || ids.length === 0 || ids.length > MAX_SOURCE_TYPES) {\n    throw new Error(`sourceTypeIds must contain 1..${MAX_SOURCE_TYPES} global IDs`);\n  }\n  return ids;\n}","typeGuard":"function isWithinSourceTypeLimit(ids) {\n  return Array.isArray(ids) && ids.length <= 50;\n}","tryCatchPattern":null,"preventionTips":["Query move targets for the types the user is actually moving, not the full catalog","Cache the type list and intersect with the UI's offered types before sending"],"tags":["graphql","work-items","batch-limit","argument-validation","gitlab-api"],"backgroundTag":"graphql-batch-size-limit","analyzedSha":"55ee20384a1f55cb0e362dee1d07149613b1b9bf","analyzedAt":"2026-08-21T14:22:27.782Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}