ytti/oxidized · error · KeyError

hook.password is required

Error message

hook.password is required

What it means

The xmppdiff hook validates at startup that jid, password, channel and nick are all present; a missing password raises KeyError 'hook.password is required' (lib/oxidized/hook/xmppdiff.rb:45). The password authenticates the JID against the XMPP server via @client.auth(cfg.password) in connect; without it the hook cannot log in to post diffs to the MUC.

Source

Thrown at lib/oxidized/hook/xmppdiff.rb:45

        logger.info "Joined #{cfg.channel}"
      end
    rescue Timeout::Error
      logger.info "timed out"
      @client = nil
      @muc = nil
    end

    @client.on_exception do
      logger.info "XMPP connection aborted, reconnecting"
      @client = nil
      @muc = nil
      connect
    end
  end

  def validate_cfg!
    raise KeyError, 'hook.jid is required' unless cfg.has_key?('jid')
    raise KeyError, 'hook.password is required' unless cfg.has_key?('password')
    raise KeyError, 'hook.channel is required' unless cfg.has_key?('channel')
    raise KeyError, 'hook.nick is required' unless cfg.has_key?('nick')
  end

  def run_hook(ctx)
    return unless ctx.node
    return unless ctx.event.to_s == "post_store"

    begin
      Timeout.timeout(15) do
        gitoutput = ctx.node.output.new
        diff = gitoutput.get_diff ctx.node, ctx.node.group, ctx.commitref, nil

        interesting = diff[:patch].lines.to_a[4..-1].any? do |line|
          ["+", "-"].include?(line[0]) && (not ["#", "!"].include?(line[1]))
        end

        if interesting

View on GitHub (pinned to 687ed4262d)

Solutions

  1. Add password: <xmpp account password> under the xmppdiff hook block (inject from your secrets manager, do not commit it)
  2. Confirm all four keys jid, password, channel, nick are present at the same indentation
  3. Restart oxidized and check the log for 'Authenticating to XMPP' to confirm the credentials work

Example fix

# before
hooks:
  xmpp:
    type: xmppdiff
    jid: oxidized@xmpp.example.com
    channel: netdev@conference.example.com
    nick: oxidized

# after
hooks:
  xmpp:
    type: xmppdiff
    jid: oxidized@xmpp.example.com
    password: secret
    channel: netdev@conference.example.com
    nick: oxidized
Defensive patterns

Strategy: validation

Validate before calling

# check the xmppdiff block before oxidized loads it
hook_cfg = YAML.load_file('/etc/oxidized/config')['hooks']['xmpp']
missing = %w[jid password channel nick].reject { |k| hook_cfg.key?(k) }
raise ArgumentError, "xmppdiff config missing: #{missing.join(', ')}" unless missing.empty?

Type guard

def xmppdiff_cfg_valid?(cfg)
  cfg.is_a?(Hash) && %w[jid password channel nick].all? { |k| cfg[k].is_a?(String) && !cfg[k].empty? }
end

Try / catch

begin
  hook.validate_cfg!
rescue KeyError => e
  abort "fix the hooks config: #{e.message}"
end

Prevention

When it happens

Trigger: A hooks block with type: xmppdiff that sets jid (and maybe channel/nick) but omits password:, or a password key removed when the config was moved to a secrets pipeline and never templated back.

Common situations: Copy-pasting the example and filling in only the JID; scrubbing secrets from the config for commit but forgetting to re-inject them on the host.

Related errors


AI-assisted analysis of ytti/oxidized@687ed4262d (2026-08-23). Data as JSON: /api/errors/32a1f08392960e29. Report an issue: GitHub.