{"record":{"id":"b879eb59b83c3972","repo":"instructure/canvas-lms","slug":"you-must-provide-targetgroupid-or-targetcontextid-and","errorCode":null,"errorMessage":"You must provide targetGroupId or targetContextId and targetContextType","messagePattern":"You must provide targetGroupId or targetContextId and targetContextType","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/import_outcomes.rb","lineNumber":320,"sourceCode":"      group\n    end\n  end\n\n  private\n\n  def get_target(input)\n    if input[:target_group_id]\n      target_group = LearningOutcomeGroup.active.find_by(id: input[:target_group_id])\n      if target_group.nil?\n        raise GraphQL::ExecutionError, I18n.t(\"no such target group\")\n      end\n\n      target_context = target_group.context\n\n      [target_context, target_group]\n    else\n      if input[:target_context_type].blank? && input[:target_context_id].blank?\n        raise GraphQL::ExecutionError, I18n.t(\n          \"You must provide targetGroupId or targetContextId and targetContextType\"\n        )\n      elsif input[:target_context_type].blank? && input[:target_context_id].present?\n        raise GraphQL::ExecutionError, I18n.t(\n          \"targetContextType required if targetContextId provided\"\n        )\n      elsif input[:target_context_type].present? && input[:target_context_id].blank?\n        raise GraphQL::ExecutionError, I18n.t(\n          \"targetContextId required if targetContextType provided\"\n        )\n      end\n\n      target_context =\n        begin\n          context_class(input[:target_context_type]).find_by(\n            id: input[:target_context_id]\n          )\n        rescue NameError","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/import_outcomes.rb#L302-L338","documentation":"ImportOutcomes requires a destination: either targetGroupId, or the pair targetContextId + targetContextType. When neither (both blank) is supplied, get_target raises this before any import runs, because there is nowhere to import outcomes into.","triggerScenarios":"Calling importOutcomes with groupId/outcomeId but omitting all target arguments; sending null/empty strings for targetGroupId, targetContextId, and targetContextType; a client bug dropping the target input fields.","commonSituations":"Older clients built before target_group_id was introduced; template requests with target fields left blank; serializers omitting empty optional fields; confusion about the two mutually compatible targeting styles.","solutions":["Pass targetGroupId of an active LearningOutcomeGroup, or both targetContextId ('1') and targetContextType ('Account' or 'Course')","If targeting a context, remember the import goes into its root_outcome_group","Validate input on the client before sending; both targetContext fields are required together","Update integrations to prefer targetGroupId (comment in code: it should become required)"],"exampleFix":"// before\nimportOutcomes(input: { outcomeId: \"42\" })\n// after\nimportOutcomes(input: { outcomeId: \"42\", targetGroupId: \"5\" });\n// or\nimportOutcomes(input: { outcomeId: \"42\", targetContextId: \"1\", targetContextType: \"Account\" });","handlingStrategy":"validation","validationCode":"function validateImportTarget(input) {\n  if (!input.targetGroupId && !(input.targetContextId && input.targetContextType)) {\n    throw new Error(\"You must provide targetGroupId or targetContextId and targetContextType\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await importOutcomes(input);\n} catch (e) {\n  if (e.message.includes(\"You must provide targetGroupId\")) {\n    // default to the current context's rootOutcomeGroup as target and retry\n  }\n}","preventionTips":["Always set a default target (current account's rootOutcomeGroup) in import UIs","Validate target fields client-side before submitting the mutation","Provide either targetGroupId or the complete targetContextId+targetContextType pair — never one alone"],"tags":["graphql","missing-argument","validation","canvas-lms"],"backgroundTag":"missing-required-argument","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}