{"record":{"id":"d69bdf8225e66f11","repo":"javan/whenever","slug":"fail-can-only-update-write-or-clear-choose-one","errorCode":null,"errorMessage":"[fail] Can only update, write or clear. Choose one.","messagePattern":"\\[fail\\] Can only update, write or clear\\. Choose one\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/whenever/command_line.rb","lineNumber":24,"sourceCode":"      new(options).run\n    end\n\n    def initialize(options={})\n      @options = options\n\n      @options[:crontab_command] ||= 'crontab'\n      @options[:file]            ||= 'config/schedule.rb'\n      @options[:cut]             ||= 0\n      @options[:identifier]      ||= default_identifier\n      @options[:console]    = true if @options[:console].nil?\n\n      if !File.exist?(@options[:file]) && @options[:clear].nil?\n        warn(\"[fail] Can't find file: #{@options[:file]}\")\n        return_or_exit(false)\n      end\n\n      if [@options[:update], @options[:write], @options[:clear]].compact.length > 1\n        warn(\"[fail] Can only update, write or clear. Choose one.\")\n        return_or_exit(false)\n      end\n\n      unless @options[:cut].to_s =~ /[0-9]*/\n        warn(\"[fail] Can't cut negative lines from the crontab #{options[:cut]}\")\n        return_or_exit(false)\n      end\n      @options[:cut] = @options[:cut].to_i\n\n      @timestamp = Time.now.to_s\n    end\n\n    def run\n      if @options[:update] || @options[:clear]\n        write_crontab(updated_crontab)\n      elsif @options[:write]\n        write_crontab(whenever_cron)\n      else","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/javan/whenever/blob/756163ed1aa928c8abd629aa2f4904bc5226538c/lib/whenever/command_line.rb#L6-L42","documentation":"whenever's three actions are mutually exclusive: --update-crontab (-i) merges into the existing crontab under the identifier, --write-crontab (-w) replaces the whole crontab, --clear-crontab (-c) removes the scheduled block. initialize counts how many of the three options were supplied and aborts with exit status 1 if more than one is present, because combining them (for example clear plus write) has no defined meaning. The bundled bin/whenever only sets each key when its flag is passed, so the count reflects actual flags.","triggerScenarios":"whenever -i -w; whenever --update-crontab myapp --clear-crontab myapp; any wrapper that concatenates flags from multiple sources, e.g. a hardcoded -i plus an env var that adds --clear-crontab, producing two or three actions in one command.","commonSituations":"Deploy scripts that evolved over time and gained a clear step before the install step; copy-pasted command lines mixing examples from different docs; deployment matrices where one flag comes from CI variables and another from the script itself.","solutions":["Pick exactly one action: -i to install/refresh, -w to overwrite, -c to remove.","If the goal is 'clear then reinstall', -i alone is enough — it atomically replaces the block marked by the identifier.","In wrapper scripts, source the action from a single variable (e.g. ACTION=${WHENEVER_ACTION:--i}) instead of appending multiple flags."],"exampleFix":"# before\nwhenever --update-crontab myapp --clear-crontab myapp\n\n# after (update already replaces the prior block for this identifier)\nwhenever --update-crontab myapp","handlingStrategy":"validation","validationCode":"actions = %i[update write clear].select { |a| opts[a] }\nabort('choose exactly one of --update-crontab, --write-crontab, --clear-crontab') unless actions.size <= 1\nWhenever::CommandLine.execute(opts)","typeGuard":"def single_action?(opts)\n  %i[update write clear].count { |a| opts[a] } <= 1\nend","tryCatchPattern":"begin\n  Whenever::CommandLine.execute(opts)\nrescue SystemExit => e\n  abort('whenever rejected the flags; supply only one action flag') unless e.success?\nend","preventionTips":["Keep the action flag in a single variable per invocation (ACTION=${WHENEVER_ACTION:--i}) instead of concatenating flags.","Remember -i/--update-crontab already replaces the previous block for the identifier — no need to clear first.","Centralize the whenever invocation in one deploy task so flags cannot accumulate from multiple scripts."],"tags":["ruby","cli","cron","mutually-exclusive","option-validation"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"756163ed1aa928c8abd629aa2f4904bc5226538c","analyzedAt":"2026-08-21T18:07:39.974Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}