{"record":{"id":"961fb9ba8de93500","repo":"presidentbeef/brakeman","slug":"parsing-path-took-too-long-timeout-secon","errorCode":null,"errorMessage":"Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout","messagePattern":"Parsing #(.+?) took too long \\(> #(.+?) seconds\\)\\. Try increasing the limit with --parser-timeout","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"lib/brakeman/file_parser.rb","lineNumber":116,"sourceCode":"        end\n      else\n        parse_with_ruby_parser input, path\n      end\n    end\n\n    private\n\n    def parse_with_prism input, path\n      Prism::Translation::RubyParser.parse(input, path)\n    end\n\n    def parse_with_ruby_parser input, path\n      begin\n        RubyParser.new.parse input, path, @timeout\n      rescue Racc::ParseError => e\n        raise e.exception(e.message + \"\\nCould not parse #{path}\")\n      rescue Timeout::Error => e\n        raise Exception.new(\"Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout\")\n      rescue => e\n        raise e.exception(e.message + \"\\nWhile processing #{path}\")\n      end\n    end\n  end\nend\n","sourceCodeStart":98,"sourceCodeEnd":123,"githubUrl":"https://github.com/presidentbeef/brakeman/blob/649e678d0a46bda0e7c35874fa7af5d16e19b4f1/lib/brakeman/file_parser.rb#L98-L123","documentation":"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.","triggerScenarios":"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`).","commonSituations":"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.","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."],"exampleFix":"# before\nbrakeman                      # Parsing lib/large_file.rb took too long (> 10 seconds)\n\n# after\nbrakeman --parser-timeout 60\n\n# or exclude the generated file\nbrakeman --skip-files lib/generated/large_file.rb","handlingStrategy":"retry","validationCode":"# Ruby, before the scan: pre-screen for oversized files and raise the timeout accordingly\nbig = Dir[File.join(app_path, '{app,lib,vendor}', '**', '*.rb')]\n  .select { |f| File.size(f) > 500_000 }\nunless big.empty?\n  warn \"Large files may exceed the parser timeout: #{big.join(', ')}\"\nend\noptions = { :app_path => app_path, :parser_timeout => 60 }  # raised from default 10","typeGuard":null,"tryCatchPattern":"# NOTE: brakeman raises bare `Exception` here (lib/brakeman/file_parser.rb:116),\n# so `rescue => e` (StandardError) will NOT catch it — rescue Exception explicitly.\nbegin\n  Brakeman.run :app_path => app_path, :parser_timeout => 30\nrescue Exception => e # rubocop:disable Lint/RescueException\n  if e.message.include?('Try increasing the limit with --parser-timeout')\n    retry_with = e.message[/took too long/]\n    abort \"Retrying with a higher --parser-timeout (#{retry_with})\"\n  end\n  raise\nend","preventionTips":["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."],"tags":["brakeman","timeout","parsing","performance","ruby-parser","large-files"],"backgroundTag":"parsing-timeout","analyzedSha":"649e678d0a46bda0e7c35874fa7af5d16e19b4f1","analyzedAt":"2026-08-21T18:43:10.938Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}