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
- 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`.
- 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.
- If the file is legitimately part of the app, split the oversized file into smaller modules so it parses within the limit.
- 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
- Pin --parser-timeout explicitly in CI (e.g. 30-60s) instead of relying on the 10s default.
- Exclude generated and vendored files from scans with --skip-files / --skip-vendor so pathological files never reach the parser.
- Keep an eye on the largest files in app/lib; a file growing past ~1MB of Ruby is a smell that will eventually time out.
- Note the timeout applies to the ruby_parser backend; prefer the Prism backend when your version supports it.
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
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Comparison file doesn't exist
- Cannot specify output format if multiple output files specif
- Invalid GitHub repository format
- Cannot find lib/ directory.
- Could not find specified check#{missing.length > 1 ? 's' : '
AI-assisted analysis of presidentbeef/brakeman@649e678d0a (2026-08-21).
Data as JSON: /api/errors/961fb9ba8de93500.
Report an issue: GitHub.