ytti/oxidized · error · KeyError
hook.token is required
Error message
hook.token is required
What it means
The slackdiff hook validates at startup that both token and channel keys exist in its config; a missing token raises KeyError 'hook.token is required' (lib/oxidized/hook/slackdiff.rb:10) while hooks load, aborting startup. The token is a Slack API token (xoxb-... bot or xoxp-... user token) that slack_ruby_client uses for auth_test, snippet upload, and chat.postMessage.
Source
Thrown at lib/oxidized/hook/slackdiff.rb:10
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 = trueView on GitHub (pinned to 687ed4262d)
Solutions
- Add the token under the slackdiff hook block: token: xoxb-1234-abcdef (inject it from your secrets manager at deploy time, do not commit it)
- Confirm both token and channel sit at the same indentation as the hook's other keys
- Restart oxidized so hook validation runs again
Example fix
# before
hooks:
slack:
type: slackdiff
channel: "#netdev-changes"
# 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
- Inject the token from a secrets manager at deploy time so the key is never accidentally dropped
- Use Slack bot tokens with minimal scopes and rotate them on a schedule
- Key-check the hooks section in CI
When it happens
Trigger: A hooks block with type: slackdiff that lacks token: (only channel set), or a token key that is misspelled or indented so it never lands in the hook's cfg hash.
Common situations: Copying the slackdiff example and forgetting the secret; intending to inject the token from an env var or secret store but leaving the literal key out of the deployed config; YAML indentation errors after adding messageformat or proxy keys.
Related errors
- hook.channel is required
- hook.remote_repo is required
- hook.jid is required
- hook.password is required
- hook.channel is required
AI-assisted analysis of ytti/oxidized@687ed4262d (2026-08-23).
Data as JSON: /api/errors/8eed2f0cab64cc47.
Report an issue: GitHub.