labml icon indicating copy to clipboard operation
labml copied to clipboard

Error: undefined method 'first_param' for an instance of Array with Ruby 3.4.1

Open greendrop opened this issue 1 year ago • 5 comments

Background

Brakeman version: 7.0.0 Rails version: 8.0.1 Ruby version: 3.4.1

Link to Rails application code: https://github.com/greendrop/ruby_3_4_1_rails_8_0_1_brakeman_7_0_0

Issue

Using it in an erb file causes an error with Ruby 3.4.1. If I didn't use it or set it to --no-prism, no error occurred.

Error: undefined method 'first_param' for an instance of Array
Location: /home/runner/work/ruby_3_4_1_rails_8_0_1_brakeman_7_0_0/ruby_3_4_1_rails_8_0_1_brakeman_7_0_0/vendor/bundle/ruby/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/template_alias_processor.rb:88:in 'Brakeman::TemplateAliasProcessor#process_iter'

Other Error

Run Brakeman with --debug to see the full stack trace.

Stack trace:

== Errors ==

Error: undefined method 'first_param' for an instance of Array
Location: /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/template_alias_processor.rb:88:in 'Brakeman::TemplateAliasProcessor#process_iter'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:76:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:184:in 'Brakeman::AliasProcessor#process_call'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:76:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:78:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:78:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/template_alias_processor.rb:81:in 'Brakeman::TemplateAliasProcessor#process_iter'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:76:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:78:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:78:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:63:in 'block in Brakeman::AliasProcessor#process_default'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Array#map!'
(eval at /Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp.rb:628):3:in 'Sexp#map!'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:61:in 'Brakeman::AliasProcessor#process_default'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/template_alias_processor.rb:81:in 'Brakeman::TemplateAliasProcessor#process_iter'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:76:in 'block in Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:113:in 'Brakeman::SexpProcessor#in_context'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/ruby_parser/bm_sexp_processor.rb:72:in 'Brakeman::SexpProcessor#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processors/alias_processor.rb:51:in 'Brakeman::AliasProcessor#process_safely'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/processor.rb:86:in 'Brakeman::Processor#process_template_alias'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:395:in 'block (2 levels) in Brakeman::Scanner#process_template_data_flows'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:65:in 'Brakeman::Scanner#process_step_file'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:394:in 'block in Brakeman::Scanner#process_template_data_flows'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:423:in 'block in Brakeman::Scanner#track_progress'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:420:in 'Array#each'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:420:in 'Brakeman::Scanner#track_progress'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:393:in 'Brakeman::Scanner#process_template_data_flows'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:126:in 'block in Brakeman::Scanner#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:51:in 'Brakeman::Scanner#process_step'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/scanner.rb:125:in 'Brakeman::Scanner#process'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman.rb:403:in 'Brakeman.scan'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman.rb:96:in 'Brakeman.run'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/commandline.rb:157:in 'Brakeman::Commandline.run_brakeman'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/commandline.rb:125:in 'Brakeman::Commandline.regular_report'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/commandline.rb:166:in 'Brakeman::Commandline.run_report'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/commandline.rb:35:in 'Brakeman::Commandline.run'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/lib/brakeman/commandline.rb:20:in 'Brakeman::Commandline.start'
/Users/greendrop/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/brakeman-7.0.0/bin/brakeman:10:in '<top (required)>'
bin/brakeman:7:in 'Kernel#load'
bin/brakeman:7:in '<main>'

greendrop avatar Jan 07 '25 08:01 greendrop

https://github.com/ruby/prism/pull/3409

presidentbeef avatar Jan 14 '25 06:01 presidentbeef

Yeah, the same issue for Rails 7.2:

bundle exec brakeman --rails7

Error: undefined method 'first_param' for an instance of Array
Location: /home/alex/.rvm/gems/ruby-3.4.1@autumn-leaves-v2/gems/brakeman-7.0.0/lib/brakeman/processors/template_alias_processor.rb:88:in 'Brakeman::TemplateAliasProcessor#process_iter'

Ruby 3.4.1 Rails Version: 7.2.2.1 Brakeman Version: 7.0.0

abratashov avatar Jan 22 '25 21:01 abratashov

As linked above, this is a Prism issue, is fixed in Prism, and I assume will be part of the next Prism release.

presidentbeef avatar Jan 22 '25 21:01 presidentbeef

So this is an it problem. I just started using it and now getting errors for the three places I'm usin git. Well, dang it :-)

Merovex avatar Mar 15 '25 10:03 Merovex

I've upgraded to the latest version of ruby (3.4.3), prism (1.4.0) and brakeman (7.0.2) and this issue persists.

Error: undefined method 'first_param' for an instance of Array
Location: /Users/mbrictson/.local/share/mise/installs/ruby/3.4.3/lib/ruby/gems/3.4.0/gems/brakeman-7.0.2/lib/brakeman/processors/template_alias_processor.rb:88:in 'Brakeman::TemplateAliasProcessor#process_iter'
  • ruby 3.4.3 (2025-04-14 revision d0b7e5b6a0) +PRISM [arm64-darwin24]
  • brakeman (7.0.2)
  • prism (1.4.0)
  • bundler (2.6.8)

The workaround, as others have mentioned, is to run brakeman with the --no-prism flag.

mattbrictson avatar Apr 15 '25 15:04 mattbrictson

Pretty confident this is fixed with Prism 1.4.0.

If problems persist, make sure Prism >= 1.4.0 is being loaded.

presidentbeef avatar Jul 09 '25 03:07 presidentbeef

I am still getting the error, and Prism 1.4.0 is definitely being loaded. Here is the ERB that is triggering the error:

<%= @post.to_html(image_path_helper: -> { vite_asset_path("images/#{it}") }, lazy_images: true) %>

The error is:

Error: undefined method 'first_param' for an instance of Array
Location: /Users/mbrictson/.local/share/mise/installs/ruby/3.4.4/lib/ruby/gems/3.4.0/gems/brakeman-7.0.2/lib/brakeman/processors/template_alias_processor.rb:88:in 'Brakeman::TemplateAliasProcessor#process_iter'

Replacing -> with lambda fixes the error:

<%= @post.to_html(image_path_helper: lambda { vite_asset_path("images/#{it}") }, lazy_images: true) %>

If this is a different underlying bug than the original issue, let me know and I can create a new bug report.

mattbrictson avatar Jul 11 '25 04:07 mattbrictson

I'm seeing the same on latest Brakeman. Not sure how to check which Prism is loaded - it's not in the gem's dependencies? Other gems in my Gemfile request Prism 1.4.0 though.

Rails Version: 7.2.2.1 Brakeman Version: 7.1.0

Not sure how to check which file is causing this, and the --debug output is extremely long.

Error: undefined method 'first_param' for an instance of Array
Location: /usr/local/bundle/gems/brakeman-7.1.0/lib/brakeman/processors/template_alias_processor.rb:88:in 'Brakeman::TemplateAliasProcessor#process_iter'

sfcgeorge avatar Jul 28 '25 13:07 sfcgeorge

Thanks @mattbrictson, I can reproduce that error.

@sfcgeorge can you check if you are also using it with an -> lambda?

presidentbeef avatar Jul 30 '25 18:07 presidentbeef

https://github.com/ruby/prism/pull/3616

presidentbeef avatar Jul 30 '25 23:07 presidentbeef