{"record":{"id":"4e9942bc29f8fd22","repo":"basecamp/kamal","slug":"error-context-message","errorCode":null,"errorMessage":"#{error_context}#{message}","messagePattern":"#\\{error_context\\}#\\{message\\}","errorType":"exception","errorClass":"Kamal::ConfigurationError","httpStatus":null,"severity":"error","filePath":"lib/kamal/configuration/validator.rb","lineNumber":184,"sourceCode":"    def validate_hooks_output!(value)\n      # hooks_output can be either a symbol/string (global) or a hash (per-hook)\n      if value.is_a?(Hash)\n        value.each do |hook, level|\n          with_context(hook) do\n            validate_type! level, String, Symbol\n          end\n        end\n      else\n        validate_type! value, String, Symbol\n      end\n    end\n\n    def validate_type!(value, *types)\n      type_error(*types) unless types.any? { |type| valid_type?(value, type) }\n    end\n\n    def error(message)\n      raise Kamal::ConfigurationError, \"#{error_context}#{message}\"\n    end\n\n    def type_error(*expected_types)\n      descriptions = expected_types.map { |type| type_description(type) }.uniq\n      error \"should be #{descriptions.join(\" or \")}\"\n    end\n\n    def unknown_keys_error(unknown_keys)\n      error \"unknown #{\"key\".pluralize(unknown_keys.count)}: #{unknown_keys.join(\", \")}\"\n    end\n\n    def error_context\n      \"#{context}: \" if context.present?\n    end\n\n    def with_context(context)\n      old_context = @context\n      @context = [ @context, context ].select(&:present?).join(\"/\")","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/basecamp/kamal/blob/eee0083b38661c3707c6b6052cc89e85038a096c/lib/kamal/configuration/validator.rb#L166-L202","documentation":"This is the single raise point for every deploy.yml schema validation failure in Kamal. The final message is the validation context path (e.g. \"accessories/db:\") joined with the concrete problem, such as \"unknown key: xyz\" or \"should be a String or Symbol\". It means Kamal parsed your YAML but a key or value does not match the configuration schema for that section.","triggerScenarios":"Any invalid deploy.yml entry: a typo'd key like enviroment: (unknown_keys_error), a wrong value type such as servers: \"1.2.3.4\" instead of a hash/array (type_error via validate_type!), or invalid nested proxy/registry/accessory settings. Raised when Kamal::Configuration is instantiated, i.e. on essentially every kamal command.","commonSituations":"Typos in YAML keys; copying example configs from docs of a different Kamal version (e.g. kamal v1 vs v2 renames); indentation mistakes that turn a mapping into a string; leaving experimental or removed options in the file after an upgrade.","solutions":["Read the context prefix before the colon in the message to locate the failing section, then fix or delete the offending key shown after it","Run kamal config (or kamal config show) to re-trigger validation and inspect the effective config once it parses","Diff your deploy.yml against the shipped template (kamal init produces config/deploy.yml) or the docs for your installed Kamal version","For type errors (\"should be ...\"), re-indent the YAML so the value is the expected mapping/array/scalar"],"exampleFix":"# deploy.yml (before)\nservers:\n  web:\n    host: 1.2.3.4   # unknown key, should be hosts\n\n# deploy.yml (after)\nservers:\n  web:\n    hosts:\n      - 1.2.3.4","handlingStrategy":"validation","validationCode":"# CI step: validate deploy.yml parses against kamal's own validator\nsystem(\"kamal config > /dev/null\") or abort \"deploy.yml is invalid — see kamal config output\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run `kamal config` as a CI check on every change to config/deploy*.yml","Pin the kamal gem version in Gemfile and re-validate config after upgrades (option names change between major versions)","Start new apps from `kamal init`'s generated config to get the current schema"],"tags":["kamal","configuration","yaml","validation","deploy"],"backgroundTag":"config-schema-validation-failed","analyzedSha":"eee0083b38661c3707c6b6052cc89e85038a096c","analyzedAt":"2026-08-21T15:17:22.045Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}