{"record":{"id":"69d0b1bc12ff79d5","repo":"javan/whenever","slug":"command-path-flags-are-required","errorCode":null,"errorMessage":":command, :path, & :flags are required","messagePattern":":command, :path, & :flags are required","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/whenever/capistrano/v2/support.rb","lineNumber":39,"sourceCode":"            map\n          end\n        end\n\n        def whenever_prepare_for_rollback args\n          if fetch(:previous_release)\n            # rollback to the previous release's crontab\n            args[:path] = fetch(:previous_release)\n          else\n            # clear the crontab if no previous release\n            args[:path]  = fetch(:release_path)\n            args[:flags] = fetch(:whenever_clear_flags)\n          end\n          args\n        end\n\n        def whenever_run_commands(args)\n          unless [:command, :path, :flags].all? { |a| args.include?(a) }\n            raise ArgumentError, \":command, :path, & :flags are required\"\n          end\n\n          whenever_server_roles.each do |server, roles|\n            roles_arg = roles.empty? ? \"\" : \" --roles #{roles.join(',')}\"\n\n            command = \"cd #{args[:path]} && #{args[:command]} #{args[:flags]}#{roles_arg}\"\n            run command, whenever_options.merge(:hosts => server)\n          end\n        end\n\n      end\n    end\n  end\nend\n","sourceCodeStart":21,"sourceCodeEnd":54,"githubUrl":"https://github.com/javan/whenever/blob/756163ed1aa928c8abd629aa2f4904bc5226538c/lib/whenever/capistrano/v2/support.rb#L21-L54","documentation":"Whenever's Capistrano 2 integration runs the whenever binary on your servers via whenever_run_commands, which requires an args hash containing :command, :path, and :flags. It raises this ArgumentError when any of those three keys is missing. The stock tasks in lib/whenever/capistrano/v2/recipes.rb (whenever:update_crontab, whenever:clear_crontab) always build the full hash, so in practice only custom tasks or reimplemented recipes that call the helper directly hit this guard. Note the check is key presence (args.include?), not nil values.","triggerScenarios":"Calling whenever_run_commands from a custom Capistrano task or callback with a partial hash, e.g. whenever_run_commands(command: 'whenever', flags: '--clear-crontab myapp') with no :path. Redefining the stock recipes inside deploy.rb (to add bundle exec or a custom user) and dropping one key. Invoking the helper from a namespace loaded before whenever/capistrano so the _cset defaults behind fetch(:whenever_command) etc. are not yet defined.","commonSituations":"Legacy Capistrano 2.x deploy.rb files copied from blog posts that reimplement the whenever tasks; teams adding roles/hosts logic and rebuilding the args hash from scratch instead of reusing fetch(:whenever_command), fetch(:whenever_update_flags), fetch(:whenever_path); upgrading whenever within Capistrano 2.x and missing a newly required key.","solutions":["Use the built-in tasks whenever:update_crontab and whenever:clear_crontab from lib/whenever/capistrano/v2/recipes.rb instead of calling whenever_run_commands yourself.","If you call the helper directly, pass all three keys: command: fetch(:whenever_command), flags: fetch(:whenever_update_flags) (or :whenever_clear_flags), path: fetch(:whenever_path).","Make sure custom tasks run after require 'whenever/capistrano' so the helper and its _cset defaults are loaded.","Wrap the call in rescue ArgumentError and re-raise with your task name to pinpoint which custom task built the bad hash."],"exampleFix":"# before (custom task, raises ':command, :path, & :flags are required')\nnamespace :custom do\n  task :cron do\n    whenever_run_commands(\n      command: 'whenever',\n      flags:   '--update-crontab myapp --set environment=production'\n    )\n  end\nend\n\n# after\nnamespace :custom do\n  task :cron do\n    whenever_run_commands(\n      command: fetch(:whenever_command),\n      flags:   fetch(:whenever_update_flags),\n      path:    fetch(:whenever_path)\n    )\n  end\nend","handlingStrategy":"validation","validationCode":"required = %i[command path flags]\nmissing = required - args.keys\nunless missing.empty?\n  abort('whenever args missing: ' + missing.join(', ') + ' in ' + task_name)\nend\nwhenever_run_commands(args)","typeGuard":"def whenever_args_complete?(args)\n  args.is_a?(Hash) && %i[command path flags].all? { |k| args.key?(k) }\nend","tryCatchPattern":"begin\n  whenever_run_commands(args)\nrescue ArgumentError => e\n  raise ArgumentError, 'custom whenever task built bad args: ' + e.message\nend","preventionTips":["Prefer the stock whenever:update_crontab / whenever:clear_crontab tasks over calling the helper directly.","Build custom args from fetch(:whenever_command), fetch(:whenever_update_flags), fetch(:whenever_path) instead of literal hashes.","Dry-run the deploy with cap --dry-run to catch argument errors before touching servers.","Define custom tasks after require 'whenever/capistrano' so helper and defaults are loaded."],"tags":["ruby","capistrano","deployment","cron","argumenterror"],"backgroundTag":"missing-required-arguments","analyzedSha":"756163ed1aa928c8abd629aa2f4904bc5226538c","analyzedAt":"2026-08-21T18:07:39.974Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}