instructure/canvas-lms · critical · ArgumentError

assets_url host for '#

Error message

assets_url host for '#{app}' must be one of: #{ALLOWED_HOSTS.join(", ")}

What it means

Raised by validate_params! when the assets_url for an app parses successfully but its host is not in ALLOWED_HOSTS. This prevents overriding release tags to point at attacker-controlled CDNs (supply-chain protection).

Solutions

  1. Use an assets_url whose host is listed in ALLOWED_HOSTS
  2. Add the legitimate new host to ALLOWED_HOSTS in the controller config
  3. Fix hostname typos and ensure the exact host (no port suffix) matches
  4. Deploy overrides only from approved infrastructure

Example fix

// before
{ override: { 'k5': 'https://evil-cdn.example.net/assets.js' } }
// after
{ override: { 'k5': 'https://cdn.instructure.com/k5/latest/assets.js' } }
Defensive patterns

Strategy: validation

Validate before calling

const u = new URL(assets_url);
if (!ALLOWED_HOSTS.includes(u.hostname)) throw new Error(`host ${u.hostname} not allowed`);

Try / catch

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

Prevention

When it happens

Trigger: Providing an assets_url pointing to an unapproved host (personal CDN, localhost, another environment's host); forgetting the port/scheme differences so uri.host doesn't match the allow-list entry; typos in the hostname.

Common situations: Engineers testing with a staging CDN host not in ALLOWED_HOSTS; DNS/CDN migration changing hostnames; trying a local dev URL in a production controller.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at app/controllers/microfrontends_release_tag_override_controller.rb:75

  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
  end
end

View on GitHub (pinned to 1c9f0bb801)