instructure/canvas-lms · error · ArgumentError

override parameter must be a hash

Error message

override parameter must be a hash

What it means

Raised by MicrofrontendsReleaseTagOverrideController#validate_params! when the override parameter does not respond to #each — i.e. it is not a hash-like structure. The controller expects params[:override] to map app names to assets URLs, and rejects anything else before iterating.

Solutions

  1. Send override as a hash/object mapping app -> assets_url, e.g. { override: { app: 'https://...' } }
  2. Ensure the request Content-Type (application/json or form encoding) matches the payload shape so Rails parses it as a hash
  3. Fix any typo in the parameter name (override, not overrides)
  4. Validate payload shape client-side before sending

Example fix

// before
{ 'override': ['k5', 'https://cdn.example.com'] }
// after
{ 'override': { 'k5': 'https://cdn.example.com' } }
Defensive patterns

Strategy: validation

Validate before calling

const override = payload.override;
if (!override || typeof override !== 'object' || Array.isArray(override)) throw new Error('override must be an object');

Type guard

const isHash = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);

Try / catch

begin
  validate_params!
rescue ArgumentError => e
  render json: { error: e.message }, status: :bad_request
end

Prevention

When it happens

Trigger: POST/PUT to the microfrontends release tag override endpoint with params[:override] missing, sent as a scalar/string, or serialized as a JSON array; sending override=null; double-encoding the payload so Rails parses it as a string.

Common situations: Scripts posting JSON without proper Content-Type so body arrives as a string; sending nested params as JSON body while the endpoint expects Rails-style form params; typos like overrides instead of override.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at app/controllers/microfrontends_release_tag_override_controller.rb:62

  def destroy
    service = MicrofrontendsReleaseTagOverrideService.new(session)
    service.clear_overrides

    redirect_to request.referer || root_url
  end

  private

  def validate_environment
    not_found unless Setting.get("allow_microfrontend_release_tag_override", "false") == "true"
  end

  def validate_params!
    override_params = params[:override]

    unless override_params.respond_to?(:each)
      raise ArgumentError, "override parameter must be a hash"
    end

    override_params.each do |app, assets_url|
      next if assets_url.blank?

      unless SUPPORTED_APPS.include?(app)
        raise ArgumentError, "app '#{app}' must be one of: #{SUPPORTED_APPS.join(", ")}"
      end

      begin
        uri = URI.parse(assets_url)
        unless ALLOWED_HOSTS.include?(uri.host)
          raise ArgumentError, "assets_url host for '#{app}' must be one of: #{ALLOWED_HOSTS.join(", ")}"
        end
      rescue URI::InvalidURIError
        raise ArgumentError, "assets_url for '#{app}' must be a valid URL"
      end
    end

View on GitHub (pinned to 1c9f0bb801)