{"record":{"id":"eb4793d9a9c65a74","repo":"instructure/canvas-lms","slug":"don-t-know-how-to-load-type","errorCode":null,"errorMessage":"don't know how to load #{type}","messagePattern":"don't know how to load #(.+?)","errorType":"exception","errorClass":"UnsupportedTypeError","httpStatus":null,"severity":"error","filePath":"app/graphql/graphql_node_loader.rb","lineNumber":352,"sourceCode":"      end\n    when \"InstitutionalTag\"\n      Loaders::IDLoader.for(InstitutionalTag).load(id).then do |tag|\n        next nil unless ctx[:domain_root_account]&.feature_enabled?(:institutional_tags)\n        next nil unless ctx[:domain_root_account]&.grants_right?(ctx[:current_user], ctx[:session], :manage_institutional_tags_view)\n\n        tag\n      end\n    when \"InstitutionalTagAssociation\"\n      Loaders::IDLoader.for(InstitutionalTagAssociation).load(id).then(check_read_permission)\n    when \"InstitutionalTagCategory\"\n      Loaders::IDLoader.for(InstitutionalTagCategory).load(id).then do |category|\n        next nil unless ctx[:domain_root_account]&.feature_enabled?(:institutional_tags)\n        next nil unless ctx[:domain_root_account]&.grants_right?(ctx[:current_user], ctx[:session], :manage_institutional_tags_view)\n\n        category\n      end\n    else\n      raise UnsupportedTypeError, \"don't know how to load #{type}\"\n    end\n  end\n\n  def self.make_permission_check(ctx, *permissions)\n    lambda do |o|\n      o&.grants_any_right?(ctx[:current_user], ctx[:session], *permissions) ? o : nil\n    end\n  end\n\n  class UnsupportedTypeError < StandardError; end\nend\n","sourceCodeStart":334,"sourceCodeEnd":364,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/graphql_node_loader.rb#L334-L364","documentation":"graphql_node_loader maps node type names to loader lambdas. If a type reaches the loader that has no registered branch (e.g. due to a typo in the node id's encoded type or an unregistered type), it raises UnsupportedTypeError 'don't know how to load <type>'.","triggerScenarios":"Querying node(id:) with a Relay id whose decoded type is not handled by the loader (typo'd or hand-encoded gid), or a feature like institutional_tags gating a branch so unlisted types fall to the else.","commonSituations":"Clients constructing global ids manually with an invalid type string; schema changes where a type was renamed but cached ids persist; loading nodes for types whose loader requires a feature flag the account lacks (falls through to else).","solutions":["Use ids returned from other GraphQL fields instead of hand-constructing them.","Verify the type name inside the gid matches a type registered in graphql_node_loader.rb.","If the branch is feature-gated (e.g. institutional_tags), enable the feature flag on the root account."],"exampleFix":"// before\nnode(id: Buffer.from('TagCategory-3').toString('base64')) // type not registered\n// after\nnode(id: <gid returned by a previous GraphQL query>)","handlingStrategy":"validation","validationCode":"function gidType(gid){ try { return UniqueWithinType.decode(gid)[0] } catch { return null } }\nif (!REGISTERED_NODE_TYPES.includes(gidType(id))) throw new Error(`node loader does not handle type ${gidType(id)}`)","typeGuard":"function isLoadableNode(gid){ const t = gidType(gid); return !!t && REGISTERED_NODE_TYPES.includes(t) }","tryCatchPattern":"try { const node = await client.request(NODE_QUERY, {id}) } catch (e) { if (e.message.includes('don't know how to load')) { /* use a gid from a prior query instead */ } else throw e }","preventionTips":["Only pass gids obtained from GraphQL responses","Check feature-flag gating for specialized node branches","Keep client type registries in sync with graphql_node_loader.rb"],"tags":["graphql","relay","loader"],"backgroundTag":"unsupported-operation","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"}