ytti/oxidized · error · KeyError

hook.channel is required

Error message

hook.channel is required

What it means

The slackdiff hook validates at startup that both token and channel keys exist in its config; a missing channel raises KeyError 'hook.channel is required' (lib/oxidized/hook/slackdiff.rb:11). The channel is where diffs are posted as snippets and where optional messages go (client.files_completeUploadExternal / chat.postMessage), so the token's bot/user must be able to post there.

Source

Thrown at lib/oxidized/hook/slackdiff.rb:11

require 'slack_ruby_client'
require 'uri'
require 'net/http'

# defaults to posting a diff, if messageformat is supplied them a message will be posted too
# diff defaults to true

class SlackDiff < Oxidized::Hook
  def validate_cfg!
    raise KeyError, 'hook.token is required' unless cfg.has_key?('token')
    raise KeyError, 'hook.channel is required' unless cfg.has_key?('channel')
  end

  def slack_upload(client, title, content, channel, proxy)
    logger.info "Posting diff as snippet to #{channel}"
    upload_dest = client.files_getUploadURLExternal(filename:     "change",
                                                    length:       content.length,
                                                    snippet_type: "diff")
    file_uri = URI.parse(upload_dest[:upload_url])

    proxy_uri = URI.parse(proxy) if proxy
    proxy_address = proxy_uri ? proxy_uri.host : :ENV
    proxy_port = proxy_uri&.port
    proxy_user = proxy_uri&.user
    proxy_pass = proxy_uri&.password

    http = Net::HTTP.new(file_uri.host, file_uri.port, proxy_address, proxy_port, proxy_user, proxy_pass)
    http.use_ssl = true

View on GitHub (pinned to 687ed4262d)

Solutions

  1. Add the channel under the slackdiff hook block: channel: "#netdev-changes" (or a channel ID like C0123456789)
  2. Keep token and channel at the same indentation as the hook's other keys
  3. Restart oxidized so hook validation runs again

Example fix

# before
hooks:
  slack:
    type: slackdiff
    token: xoxb-1234567890-abcdef

# after
hooks:
  slack:
    type: slackdiff
    token: xoxb-1234567890-abcdef
    channel: "#netdev-changes"
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

def slackdiff_cfg_valid?(cfg)
  cfg.is_a?(Hash) && %w[token channel].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: slackdiff that sets token: but omits channel:, or a channel key lost to a typo or bad YAML indentation when the block was edited.

Common situations: Copying a partial example; renaming channel to room; reindenting the hooks block while adding messageformat/diff/proxy keys.

Related errors


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