ytti/oxidized · error · KeyError

hook.jid is required

Error message

hook.jid is required

What it means

The xmppdiff hook validates at startup that all four keys jid, password, channel and nick are present; the first missing one raises KeyError (lib/oxidized/hook/xmppdiff.rb:44). 'hook.jid is required' means the Jabber ID of the account oxidized logs in with is absent. The jid is passed to Jabber::Client.new(Jabber::JID.new(cfg.jid)) in connect and is the bare JID of that account, e.g. oxidized@xmpp.example.com.

Source

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

        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

View on GitHub (pinned to 687ed4262d)

Solutions

  1. Add jid: oxidized@xmpp.example.com under the xmppdiff hook block
  2. Also provide password, channel and nick: all four keys are required or the next validate_cfg! line raises the following KeyError
  3. Restart oxidized and watch the log for hook validation

Example fix

# before
hooks:
  xmpp:
    type: xmppdiff
    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 omits jid: (typically only channel/nick were copied from an example), or a jid key lost to indentation or renaming (user/username).

Common situations: Copying a partial xmppdiff example; storing XMPP credentials outside the config and forgetting to template them in; editing the hooks block and breaking indentation.

Related errors


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