instructure/canvas-lms · error · GraphQL::ExecutionError

Must specify exactly one of id or name

Error message

Must specify exactly one of id or name

What it means

The `internal_setting` resolver requires exactly one of an `id` (graphql/legacy ID) or a `name` (the Setting's string name). Both or neither is ambiguous and raises this GraphQL::ExecutionError before loading the node.

Solutions

  1. Pass exactly one of id or name; drop the other.
  2. If you only know the setting name, use the name path and omit id entirely.
  3. Omit unset variables so empty strings are not serialized as present arguments.

Example fix

// before
query { internalSetting(id: "12", name: "DefaultMigrationDelay") { value } }
// after
query { internalSetting(name: "DefaultMigrationDelay") { value } }
Defensive patterns

Strategy: validation

Validate before calling

const n = [vars.id, vars.name].filter(v => v != null && v !== '').length;
if (n !== 1) throw new Error('internalSetting requires exactly one of id or name');

Type guard

const settingArgsValid = (vars) => Boolean(vars.id) !== Boolean(vars.name);

Try / catch

try { return await gql(SETTING_QUERY, vars); } catch (e) { if (e.message.includes('exactly one of id or name')) { vars = vars.id ? { id: vars.id } : { name: vars.name }; return retry(vars); } throw e; }

Prevention

When it happens

Trigger: query { internalSetting(id: "...", name: "...") } (both) or query { internalSetting } with neither argument.

Common situations: Ops tooling that normally looks settings up by name keeps a stale id variable after a refactor; scripts that template all optional arguments into the query; empty-string name serializing alongside an id.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/3a20c5bcfa8c0746. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/types/query_type.rb:350

               "a graphql or legacy id",
               required: true,
               prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("LearningOutcome")
    end
    def learning_outcome(id:)
      GraphQLNodeLoader.load("LearningOutcome", id, context)
    end

    field :internal_setting, Types::InternalSettingType, null: true do
      description "Retrieves a single internal setting by its ID or name"
      argument :id,
               ID,
               "a graphql or legacy id",
               required: false,
               prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("InternalSetting")
      argument :name, String, "the name of the Setting", required: false
    end
    def internal_setting(id: nil, name: nil)
      raise GraphQL::ExecutionError, "Must specify exactly one of id or name" if (id && name) || !(id || name)

      return GraphQLNodeLoader.load("InternalSetting", id, context) if id

      GraphQLNodeLoader.load("InternalSettingByName", name, context) if name
    end

    field :internal_settings, [Types::InternalSettingType], null: true do
      description "All internal settings"
    end
    def internal_settings
      return [] unless Account.site_admin.grants_right?(context[:current_user], context[:session], :manage_internal_settings)

      Setting.all
    end

    field :account_notifications, [Types::AccountNotificationType], null: false do
      description "Account notifications for the current user"
      argument :account_id, ID, "Account ID to fetch notifications for", required: false

View on GitHub (pinned to 1c9f0bb801)