{"record":{"id":"d62d0549d1054f95","repo":"whitesmith/rubycritic","slug":"could-not-create-reporter-for-class-path-error","errorCode":null,"errorMessage":"Could not create reporter for class #{path}. Error: #{error}!","messagePattern":"Could not create reporter for class #(.+?)\\. Error: #(.+?)!","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/rubycritic/reporter.rb","lineNumber":36,"sourceCode":"        require \"rubycritic/generators/#{config_format}_report\"\n        Generator.const_get(\"#{config_format.capitalize}Report\")\n      else\n        require 'rubycritic/generators/html_report'\n        Generator::HtmlReport\n      end\n    end\n\n    def self.report_generator_class_from_formatter(formatter)\n      require_path, class_name = formatter.sub(/([^:]):([^:])/, '\\1\\;\\2').split('\\;', 2)\n      class_name ||= require_path\n      require require_path unless require_path == class_name\n      class_from_path(class_name)\n    end\n\n    def self.class_from_path(path)\n      path.split('::').inject(Object) { |obj, klass| obj.const_get klass }\n    rescue NameError => error\n      raise \"Could not create reporter for class #{path}. Error: #{error}!\"\n    end\n  end\nend\n","sourceCodeStart":18,"sourceCodeEnd":40,"githubUrl":"https://github.com/whitesmith/rubycritic/blob/a70e68cdee9b99e1f8567430850ffff1bbad273e/lib/rubycritic/reporter.rb#L18-L40","documentation":"RubyCritic resolves each custom formatter spec (from --custom-format on the CLI or the :formatters config option) into a Ruby class by walking the constant path: path.split('::').inject(Object) { |obj, klass| obj.const_get klass } in lib/rubycritic/reporter.rb:33-37. When any segment of that lookup raises NameError (uninitialized constant, wrong constant name, or a missing nesting level), RubyCritic catches it and re-raises this RuntimeError wrapping the original NameError text. It means the formatter file may have loaded fine, but the class named in your formatter spec was not found at that constant path when the report was generated.","triggerScenarios":"Calling `rubycritic --custom-format <requirepath>:<Class::Name>` (or setting RubyCritic::Config.formatters / the rake task's options with --custom-format) where: (1) the class name is misspelled or wrongly cased — e.g. `my_formatter` instead of `MyFormatter`, which makes Object#const_get raise 'wrong constant name'; (2) the class is namespaced, e.g. defined as MyGem::MyFormatter, but the spec passes only `MyFormatter` or the wrong nesting; (3) the spec is class-name-only (no `:` separator) — RubyCritic then skips the require entirely (reporter.rb:29 requires only when require_path != class_name), so unless your Rakefile already required the file, the constant is never loaded; (4) the require path resolved but the file defines a differently-named class.","commonSituations":"Following the docs' Rakefile example but forgetting `require 'my_formatter'` before `RubyCritic::RakeTask.new`; running rubycritic from the CLI with only a class name for a formatter that lives in a gem you never required; copy-pasting a formatter spec where the file is snake_case and passing the snake_case string as the class name; upgrading a formatter gem (e.g. rubycritic-small-badge) whose class moved or was renamed between versions; environments where the formatter is autoloaded in the app (Zeitwerk) but not on the rubycritic CLI process.","solutions":["Fix the class name in the --custom-format spec to the exact constant: correct CamelCase and full namespace, e.g. `--custom-format my_formatter:MyFormatter` or `--custom-format my_gem:MyGem::MyFormatter`.","If you pass only a class name (no `:` separator), require the formatter file yourself before the task — in the Rakefile put `require 'my_formatter'` above `RubyCritic::RakeTask.new` — because RubyCritic skips the require when require path and class name are identical.","Prefer the `requirepath:Class::Name` form (e.g. `rubycritic --custom-format my_formatter:MyFormatter`) so RubyCritic performs the require for you.","Verify the constant loads standalone in the same context: `bundle exec ruby -e \"require 'my_formatter'; p MyFormatter\"` — if this fails, fix the gem's load path or Gemfile inclusion first.","Check for a namespace/file-name mismatch: the class must exist at top level (Object) unless you spell out the full `Namespace::Chain` in the spec. A LoadError instead of this message means the require path itself is wrong or the gem is not installed.","If the formatter gem changed in a recent upgrade, check its CHANGELOG for renamed or moved formatter classes and pin the known-good version until you update the spec."],"exampleFix":"# before (Rakefile) — class never loaded, spec has no require path:\nRubyCritic::RakeTask.new do |task|\n  task.options = '--custom-format MyFormatter'\nend\n# => RuntimeError: Could not create reporter for class MyFormatter.\n#    Error: uninitialized constant MyFormatter!\n\n# after — require the file first, and pass require path + class name:\nrequire 'my_formatter'\n\nRubyCritic::RakeTask.new do |task|\n  task.options = '--custom-format my_formatter:MyFormatter'\nend\n\n# for a namespaced formatter, spell out the full constant path:\n#   rubycritic --custom-format my_gem:MyGem::MyFormatter","handlingStrategy":"validation","validationCode":"# Run before invoking RubyCritic (rake task or API) to fail fast with a clear\n# message instead of the generic RuntimeError mid-report. Splits the spec on the\n# first single colon (not part of '::'), mirrors the library's require logic, and\n# checks the constant path resolves to a Class implementing #generate_report.\ndef rubycritic_formatter_resolvable?(spec)\n  require_path, class_name = spec.split(/:(?!:)/, 2)\n  class_name ||= require_path\n  require require_path unless require_path == class_name\n  klass = class_name.split('::').inject(Object) do |mod, name|\n    return false unless mod.const_defined?(name.to_sym)\n    mod.const_get(name.to_sym)\n  end\n  klass.is_a?(Class) && klass.public_method_defined?(:generate_report)\nrescue LoadError, NameError\n  false\nend\n\nRubyCritic::Config.formatters.all? { |s| rubycritic_formatter_resolvable?(s) } or\n  abort 'formatter spec is not resolvable — check class name casing/namespace'","typeGuard":"# Ruby 'type guard': predicate that a formatter spec resolves to a Class\n# implementing the formatter interface (#generate_report, initialized with\n# analysed_modules).\ndef valid_rubycritic_formatter?(spec)\n  require_path, class_name = spec.split(/:(?!:)/, 2)\n  class_name ||= require_path\n  require require_path unless require_path == class_name\n  klass = class_name.split('::').inject(Object) do |mod, name|\n    return false unless mod.const_defined?(name.to_sym)\n    mod.const_get(name.to_sym)\n  end\n  klass.is_a?(Class) && klass.public_method_defined?(:generate_report)\nrescue StandardError\n  false\nend","tryCatchPattern":"# The library raises a plain RuntimeError (string message, no dedicated error\n# class), so match on the message prefix and rescue narrowly — keep other\n# errors fatal.\nbegin\n  RubyCritic::Reporter.generate_report(analysed_modules)\nrescue RuntimeError => e\n  raise unless e.message.start_with?('Could not create reporter for class')\n  warn \"Custom formatter failed to load: #{e.message}\"\n  warn 'Check the class name casing/namespace, or require the formatter file first.'\n  exit 1\nend","preventionTips":["Always use the `requirepath:Fully::Qualified::Class` form of --custom-format so RubyCritic does the require itself.","The class name is a Ruby constant: exact CamelCase, leading uppercase letter, full namespace chain — snake_case names raise 'wrong constant name'.","With the class-name-only form, put `require 'your_formatter'` in the Rakefile before `RubyCritic::RakeTask.new`; otherwise nothing loads the class.","Smoke-test the load in the same process context before CI: `bundle exec ruby -e \"require 'x'; p X\"` plus a check that X responds to #generate_report.","When upgrading formatter gems, diff the constant path (renames/moves) and update the spec; a LoadError instead of this message means the require path — not the class name — is wrong."],"tags":["ruby","rubycritic","custom-formatter","constget","nameerror","classloading","rake-task","cli"],"backgroundTag":"uninitialized-constant","analyzedSha":"a70e68cdee9b99e1f8567430850ffff1bbad273e","analyzedAt":"2026-08-23T10:29:35.945Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}