instructure/canvas-lms · error · ArgumentError

Need more arguments

Error message

Need more arguments

What it means

canvas_crummy's add_crumb (controller method) builds a navigation crumb from a name and/or url/block. At least one of a name argument or a block is required — without either there's nothing to render — so it raises ArgumentError. (A companion check forbids passing both a url and a block.)

Solutions

  1. Pass a name: add_crumb('Courses', courses_path)
  2. Use a block for lazy names: add_crumb { |c| c.name }
  3. Ensure a dynamically computed name variable is non-nil, or default it
  4. If a URL is passed with dynamic naming, pass name explicitly rather than relying on a block

Example fix

// before
add_crumb(class: 'strong')
// after
add_crumb('Dashboard', class: 'strong')
Defensive patterns

Strategy: validation

Validate before calling

raise 'add_crumb needs name or block' if name.nil? && !block_given?

Try / catch

begin
  add_crumb(name, url)
rescue ArgumentError => e
  Rails.logger.warn("bad crumb: #{e.message}")
end

Prevention

When it happens

Trigger: Calling add_crumb() with no arguments and no block, e.g. add_crumb in a controller; calling add_crumb(options...) where the name positional is nil at runtime and no block is attached; dynamic name via block that was accidentally removed.

Common situations: Refactoring breadcrumbs to compute names lazily but dropping the block; passing only html-style options (:class/:id) and forgetting the name; conditional code where name falls through nil.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at gems/canvas_crummy/lib/canvas_crummy/controller_methods.rb:39

  module ControllerMethods
    module ClassMethods
      # Add a crumb to the crumbs array.
      #
      #   add_crumb("Home", "/")
      #   add_crumb("Business") { |instance| instance.business_path }
      #
      # Works like a before_filter so +:only+ and +except+ both work.
      def add_crumb(name, *args)
        options = args.extract_options!
        url = args.first
        # I wanted this next line to look more like:
        # html_options = options.pluck { |k,v| %w{class id}.include? k.to_s  }
        # but couldn't figure out how
        html_options = (klass = options.delete(:class)) ? { class: klass } : {}
        if (id = options.delete(:id))
          html_options[:id] = id
        end
        raise ArgumentError, "Need more arguments" unless name || block_given?
        raise ArgumentError, "Cannot pass url and use block" if url && block_given?

        before_action(options) do |instance|
          url_value = url
          url_value = yield instance if block_given?
          url_value = instance.send url_value if url_value.is_a? Symbol
          name_value = name
          name_value = instance.instance_eval(&name_value) if name_value.is_a? Proc
          name_value = instance.instance_variable_get(:"@#{name_value}") if name_value.is_a? Symbol
          record = instance.instance_variable_get(:"@#{name_value}") unless url_value || block_given?
          if record
            name_value, url_value = record.to_s, instance.url_for(record)
          end

          # FIXME: url_value = instance.url_for(name_value) if name_value.respond_to?("to_param") && url_value.nil?
          # FIXME: Add ||= for the name_value, url_value above
          instance.add_crumb(name_value, url_value, html_options)
        end

View on GitHub (pinned to 1c9f0bb801)