presidentbeef/brakeman · error · Exception

Parsing #{path} took too long (> #{@timeout} seconds). Try i

Error message

Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout

What it means

Brakeman enforces a per-file parse timeout (default 10 seconds, settable via `--parser-timeout SECONDS`) when parsing Ruby source with the ruby_parser backend. When `RubyParser.new.parse` raises `Timeout::Error`, the rescue block re-raises a generic `Exception` with this message and the scan aborts. Note two quirks: it is raised as bare `Exception` (not `StandardError`), and the timeout only applies to the ruby_parser path, not the Prism parser.

Source

Thrown at lib/brakeman/file_parser.rb:116

        end
      else
        parse_with_ruby_parser input, path
      end
    end

    private

    def parse_with_prism input, path
      Prism::Translation::RubyParser.parse(input, path)
    end

    def parse_with_ruby_parser input, path
      begin
        RubyParser.new.parse input, path, @timeout
      rescue Racc::ParseError => e
        raise e.exception(e.message + "\nCould not parse #{path}")
      rescue Timeout::Error => e
        raise Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout")
      rescue => e
        raise e.exception(e.message + "\nWhile processing #{path}")
      end
    end
  end
end

View on GitHub (pinned to 649e678d0a)

Solutions

  1. Raise the limit: `brakeman --parser-timeout 30` (or higher) for the scan, or set `:parser_timeout: 30` in a brakeman config file passed with `-c`.
  2. Identify the file named in the message and exclude it if it is generated/vendored: `--skip-files path/to/file.rb` or `--ignore-config ignore-file.json` with a fingerprint/entry for it.
  3. If the file is legitimately part of the app, split the oversized file into smaller modules so it parses within the limit.
  4. Speed up the environment (faster CI runner, warm caches, disable competing jobs) so the 10s default is sufficient, or switch to the Prism parser backend if available in your Brakeman version, since the timeout applies to the ruby_parser code path.

Example fix

# before
brakeman                      # Parsing lib/large_file.rb took too long (> 10 seconds)

# after
brakeman --parser-timeout 60

# or exclude the generated file
brakeman --skip-files lib/generated/large_file.rb
Defensive patterns

Strategy: retry

Validate before calling

# Ruby, before the scan: pre-screen for oversized files and raise the timeout accordingly
big = Dir[File.join(app_path, '{app,lib,vendor}', '**', '*.rb')]
  .select { |f| File.size(f) > 500_000 }
unless big.empty?
  warn "Large files may exceed the parser timeout: #{big.join(', ')}"
end
options = { :app_path => app_path, :parser_timeout => 60 }  # raised from default 10

Try / catch

# NOTE: brakeman raises bare `Exception` here (lib/brakeman/file_parser.rb:116),
# so `rescue => e` (StandardError) will NOT catch it — rescue Exception explicitly.
begin
  Brakeman.run :app_path => app_path, :parser_timeout => 30
rescue Exception => e # rubocop:disable Lint/RescueException
  if e.message.include?('Try increasing the limit with --parser-timeout')
    retry_with = e.message[/took too long/]
    abort "Retrying with a higher --parser-timeout (#{retry_with})"
  end
  raise
end

Prevention

When it happens

Trigger: Scanning an app that contains a single very large or pathological Ruby file that takes more than `--parser-timeout` (default 10) seconds to parse — e.g. huge generated files, bundled vendor code, big migrated data scripts — or running on a slow/oversubscribed CI machine where even normal files exceed 10 seconds. Also triggered by explicitly setting `--parser-timeout` too low (the test suite reproduces it with `parser_timeout: 0.5`).

Common situations: Vendored gems or generated files inside the app tree with tens of thousands of lines; shared CI runners with starved CPU making the 10s default too tight; a schema/tool-generated `routes` or constants file that grew over time; upgrading Brakeman versions where the default stayed 10s but the app grew past it.

Understand the failure class

Related errors


AI-assisted analysis of presidentbeef/brakeman@649e678d0a (2026-08-21). Data as JSON: /api/errors/961fb9ba8de93500. Report an issue: GitHub.