instructure/canvas-lms · error

Please don't turn off the default developer key

Error message

Please don't turn off the default developer key

What it means

DeveloperKeyAccountBinding#protect_default_key_binding enforces that the account binding for the site default developer key is always workflow_state :on, because the default key must remain usable for user-generated tokens. Turning the binding off (or deleting it) triggers this raise.

Solutions

  1. Never set the default key's binding to :off/:allow; leave it :on
  2. Exclude the default key's binding from bulk disable scripts (skip where binding.for_default_key?)
  3. Use the enable_default_key path (it auto-forces :on) rather than manually setting workflow_state
  4. If the intent is to restrict LTI tools, disable the specific tool keys, not the default key binding

Example fix

// before
binding.workflow_state = :off
binding.save!
// after
raise "cannot disable default key binding" if binding.for_default_key?
binding.workflow_state = :off
binding.save!
Defensive patterns

Strategy: validation

Validate before calling

next if binding.for_default_key? # skip default key bindings
binding.update(workflow_state: :off)

Try / catch

begin
  binding.update!(workflow_state: :off)
rescue RuntimeError => e
  raise unless e.message =~ /default developer key/
  Rails.logger.warn('cannot disable default key binding')
end

Prevention

When it happens

Trigger: Setting workflow_state to :off/:allow on a binding where for_default_key? is true (binding whose developer_key is DeveloperKey.default); deleting the default key's binding; account-level API updates that disable the default key.

Common situations: Admin toggling 'off' on the default key in an account settings page; scripts bulk-disabling developer key bindings per account; API PATCH to developer_key_account_bindings targeting the default key.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at app/models/developer_key_account_binding.rb:162

  end

  alias_method :allowed?, :allow?

  private

  def for_default_key?
    developer_key&.name == DeveloperKey::DEFAULT_KEY_NAME &&
      developer_key == DeveloperKey.default(create_if_missing: false)
  end

  # DeveloperKey.default is for user-generated tokens and must always be ON
  def enable_default_key
    self.workflow_state = :on if !on? && for_default_key?
  end

  # DeveloperKey.default is for user-generated tokens and must always be ON
  def protect_default_key_binding
    raise "Please don't turn off the default developer key" if !on? && for_default_key?
  end

  def set_root_account
    self.root_account_id ||= account&.resolved_root_account_id
  end

  def update_tools!
    if disable_tools? || delete_tools?
      developer_key.disable_external_tools!(account)
    elsif enable_tools?
      developer_key.enable_external_tools!(account)
    elsif restore_tools?
      developer_key.restore_external_tools!(account)
    end
  end

  def enable_tools?
    saved_change_to_workflow_state? && on?

View on GitHub (pinned to 1c9f0bb801)