sds/overcommit · error · Overcommit::Exceptions::HookLoadError
Unable to load hook '#{hook_name}': #{e}
Error message
Unable to load hook '#{hook_name}': #{e} What it means
The ad hoc twin of the create_hook failure: for hooks declared only in .overcommit.yml (no plugin file), PluginHookLoader#create_ad_hoc_hook builds an anonymous subclass of the hook type's Base and registers it with const_set. The rescue fires when Overcommit::Hook.const_get(@context.hook_class_name) or const_get('Base') raises NameError - the configured hook type has no matching module or Base class - and wraps it as 'Unable to load hook'.
Source
Thrown at lib/overcommit/hook_loader/plugin_hook_loader.rb:97
hook_base = hook_module.const_get('Base')
# Implement a simple class that executes the command and returns pass/fail
# based on the exit status
hook_class = Class.new(hook_base) do
def run
result = @context.execute_hook(command)
if result.success?
:pass
else
[:fail, result.stdout + result.stderr]
end
end
end
hook_module.const_set(hook_name, hook_class).new(@config, @context)
rescue LoadError, NameError => e
raise Overcommit::Exceptions::HookLoadError,
"Unable to load hook '#{hook_name}': #{e}",
e.backtrace
end
end
end
View on GitHub (pinned to fee0cd74b2)
Solutions
- Check the wrapped NameError in the message - it names the constant that could not be resolved
- Spell hook type sections with Overcommit's exact CamelCase names (PreCommit:, CommitMsg:, PrePush:) and put ad hoc hooks under those keys
- Confirm the hook type exists in your installed version via 'overcommit --list' or Overcommit::Utils.supported_hook_types
- Upgrade the overcommit gem if the config targets a newer hook type
Example fix
# before (.overcommit.yml)
Precommit:
MyCheck:
required_executable: ./bin/check.sh
# after
PreCommit:
MyCheck:
required_executable: ./bin/check.sh Defensive patterns
Strategy: validation
Validate before calling
require 'yaml'
config = YAML.load_file('.overcommit.yml')
known = %w[plugin_directory gemfile verify_plugin_signatures] +
Overcommit::Utils.supported_hook_types.map { |t| Overcommit::Utils.camel_case(t) }
unknown = config.keys.map(&:to_s) - known
abort "Unknown hook type section(s): #{unknown.join(', ')}" unless unknown.empty? Type guard
def supported_hook_section?(key)
Overcommit::Utils.supported_hook_types.any? { |t| Overcommit::Utils.camel_case(t) == key.to_s }
end Try / catch
begin
runner.run
rescue Overcommit::Exceptions::HookLoadError => e
abort "Fix .overcommit.yml hook type sections: #{e.message}"
end Prevention
- Validate .overcommit.yml section keys in CI with the snippet above
- Copy section names from Overcommit's default config instead of typing them from memory
When it happens
Trigger: An enabled ad hoc hook (a config-only entry with required_executable/command) runs during load_hooks when its hook type section does not match a module under Overcommit::Hook - e.g. a misspelled section key like 'Precommit:' instead of 'PreCommit:' - or the installed Overcommit defines no <Type>::Base for that hook type.
Common situations: Typo in a .overcommit.yml section header (Precommit vs PreCommit); copy-pasted config using a hook type the installed Overcommit version does not support; casing changed while refactoring YAML config.
Related errors
- Unable to load hook '#{hook_name}': #{e}
- Class #{hook_name} is not a subclass of #{hook_base_class}.
- A load error occurred. Did you forget to install a gem? #{e.
- Hook specified a `required_executable` or `command` that is
- Unable to write to local repo git config: #{result.stderr}
AI-assisted analysis of sds/overcommit@fee0cd74b2 (2026-08-23).
Data as JSON: /api/errors/ad90a605f6f1b433.
Report an issue: GitHub.