ytti/oxidized · error · OxidizedError
mechanize not found: sudo gem install mechanize
Error message
mechanize not found: sudo gem install mechanize
What it means
The HTTP input needs mechanize only when the node's model defines main_page together with a login callback (form-based login); connect then lazily requires 'mechanize' and converts LoadError into OxidizedError 'mechanize not found: sudo gem install mechanize' (lib/oxidized/input/http.rb:17-21). Without a login flow the input uses plain Net::HTTP and the gem is never required, so the error only appears for login-protected HTTP models.
Source
Thrown at lib/oxidized/input/http.rb:20
require "net/http"
require "json"
require "net/http/digest_auth"
class HTTP < Input
def connect(node)
@node = node
@secure = false
@username = nil
@password = nil
@headers = {}
@node.model.cfg["http"].each { |cb| instance_exec(&cb) }
return true unless @main_page && defined?(login)
begin
require "mechanize"
rescue LoadError
raise OxidizedError, "mechanize not found: sudo gem install mechanize"
end
@m = Mechanize.new
url = URI::HTTP.build host: @node.ip, path: @main_page
@m_page = @m.get(url.to_s)
login
end
def cmd(callback_or_string)
return cmd_cb callback_or_string if callback_or_string.is_a?(Proc)
cmd_str callback_or_string
end
def cmd_cb(callback)
instance_exec(&callback)
end
View on GitHub (pinned to 687ed4262d)
Solutions
- Install the gem into the same Ruby oxidized runs with: sudo gem install mechanize (for distro packages, in the system gem home; for bundler, add gem 'mechanize' to the Gemfile and run bundle install)
- Verify with the service context: gem list mechanize and ruby -e "require 'mechanize'" using the same RUBY/GEM_HOME oxidized uses (check gem env)
- If the device needs no form login, remove main_page/login from the model so the plain Net::HTTP path runs without mechanize
- Rebuild docker images to include mechanize when any http model uses login
Example fix
# before (Gemfile) gem 'oxidized' # runtime: OxidizedError: mechanize not found: sudo gem install mechanize # after (Gemfile) gem 'oxidized' gem 'mechanize' # then: bundle install
Defensive patterns
Strategy: validation
Validate before calling
# fail fast at boot when any http model uses a login flow begin gem 'mechanize' rescue Gem::LoadError warn 'mechanize is missing: http input with login will raise OxidizedError'; exit 1 end
Type guard
def mechanize_available? require 'mechanize' true rescue LoadError false end
Try / catch
begin
input.connect(node)
rescue OxidizedError => e
logger.error "#{node.name}: #{e.message}"
raise
end Prevention
- Pin mechanize in the same Gemfile/lockfile as oxidized whenever an http model uses login
- Bake gem checks into container builds: RUN gem install mechanize
- After switching rubies or upgrade paths, run ruby -e "require 'mechanize'" as the service user
When it happens
Trigger: Setting input: http on a node whose model has main_page (e.g. main_page '/login.html') and a login block, while the mechanize gem is not installed in the Ruby/gemset that actually runs oxidized (distro package install, bundler project without the gem, or a container image missing it).
Common situations: Installing oxidized via apt/deb where mechanize is an optional extra; running under bundler with a Gemfile that omits mechanize; switching a device from ssh/telnet to http input with a login page; CI or docker images built before any http-login model was used.
Related errors
- #{self.class.name}: configuration invalid: #{e.message}
- #{@cmd} timed out
- hook.remote_repo is required
- hook.token is required
- hook.channel is required
AI-assisted analysis of ytti/oxidized@687ed4262d (2026-08-23).
Data as JSON: /api/errors/f5bc61e5283a5df6.
Report an issue: GitHub.