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

not found

Error message

not found

What it means

This is a generic rescue in the UpdateInternalSetting GraphQL mutation: when the lookup of the internal setting record raises ActiveRecord::RecordNotFound, it is converted into a GraphQL::ExecutionError with the unhelpful message "not found". Canvas raises it so clients get a normal GraphQL error instead of an unhandled 500.

Solutions

  1. Verify the internal_setting id/name passed in the mutation arguments exists (e.g. InternalSetting.find in console).
  2. Check you are operating on the correct database/shard where the setting lives.
  3. Correct the client input so it references a valid setting id.
  4. If a legitimately missing setting should be a no-op, handle it before calling the mutation instead of relying on the error.

Example fix

// before
mutation {
  updateInternalSetting(input: {internalSettingId: "123"}) { ... }
}
// after
# resolve by the real setting name/id first:
# setting = InternalSetting.find_by(name: "my_setting")
mutation {
  updateInternalSetting(input: {internalSettingId: "42"}) { ... }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// resolve the setting first
const setting = await gql(FETCH_INTERNAL_SETTING, { id });
if (!setting?.internalSetting) throw new NotFoundError(id);

Type guard

function hasInternalSetting(data) { return data?.internalSetting != null; }

Try / catch

try {
  await gql(UPDATE_INTERNAL_SETTING, { internalSettingId: id });
} catch (e) {
  if (e.message === 'not found') { /* surface 'setting not found' to user */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling updateInternalSetting with an `internal_setting` id (or name) that does not match any InternalSetting row in the database.

Common situations: Typoed setting name/id; querying a setting that only exists on a different shard or environment; setting deleted before the mutation ran; staging vs production data mismatch.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/update_internal_setting.rb:40

  argument :internal_setting_id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("InternalSetting")
  argument :value, String, required: true

  field :internal_setting, Types::InternalSettingType, null: false
  def resolve(input:)
    if !Account.site_admin.grants_right?(current_user, :manage_internal_settings) || (internal_setting = Setting.find(input[:internal_setting_id])).secret
      raise GraphQL::ExecutionError, "insufficient permission"
    end

    unless input[:value].nil?
      Setting.set(internal_setting.name, input[:value])
      internal_setting.reload
    end

    {
      internal_setting:
    }
  rescue ActiveRecord::RecordNotFound
    raise GraphQL::ExecutionError, "not found"
  end
end

View on GitHub (pinned to 1c9f0bb801)