{"record":{"id":"98f250ecf0a8a9b2","repo":"puppetlabs/puppet","slug":"cannot-use-a-term-and-b-term-at-the-same","errorCode":null,"errorMessage":"Cannot use '%{a_term}' and '%{b_term}' at the same time","messagePattern":"Cannot use '%(.+?)' and '%(.+?)' at the same time","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pal/pal_impl.rb","lineNumber":573,"sourceCode":"    Puppet::Pops::Types::TypeFactory.pattern(/\\A[a-z][a-z0-9_]*\\z/), Puppet::Pops::Types::TypeFactory.data\n  )\n\n  def self.assert_type(type, value, what, allow_nil = false)\n    Puppet::Pops::Types::TypeAsserter.assert_instance_of(nil, type, value, allow_nil) { _('Puppet Pal: %{what}') % { what: what } }\n  end\n\n  def self.assert_non_empty_string(s, what, allow_nil = false)\n    assert_type(T_STRING, s, what, allow_nil)\n  end\n\n  def self.assert_optionally_empty_array(a, what, allow_nil = false)\n    assert_type(T_STRING_ARRAY, a, what, allow_nil)\n  end\n  private_class_method :assert_optionally_empty_array\n\n  def self.assert_mutually_exclusive(a, b, a_term, b_term)\n    if a && b\n      raise ArgumentError, _(\"Cannot use '%{a_term}' and '%{b_term}' at the same time\") % { a_term: a_term, b_term: b_term }\n    end\n  end\n  private_class_method :assert_mutually_exclusive\n\n  def self.assert_block_given(block)\n    if block.nil?\n      raise ArgumentError, _(\"A block must be given\")\n    end\n  end\n  private_class_method :assert_block_given\nend\nend\n","sourceCodeStart":555,"sourceCodeEnd":586,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pal/pal_impl.rb#L555-L586","documentation":"PAL's assert_mutually_exclusive raises ArgumentError when both of a forbidden pair are truthy. It guards the (manifest_file, code_string) pair and the (env_dir, envpath) pair on the PAL entry points - only one of each pair may be supplied.","triggerScenarios":"Passing manifest_file AND code_string to a PAL compiler call; passing env_dir AND envpath to in_environment.","commonSituations":"Wrapper APIs forwarding user options straight into PAL so both get set from config files; option precedence never decided upstream.","solutions":["Supply only one of each pair (manifest_file or code_string; env_dir or envpath)","In wrappers, apply precedence before delegating: manifest_file = nil if code_string","Raise your own descriptive error early when the caller sets both"],"exampleFix":"# before\nPuppet::Pal.in_environment('prod', env_dir: d, envpath: p) { |c| }\n\n# after\nPuppet::Pal.in_environment('prod', env_dir: d) { |c| }","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'pass env_dir OR envpath, not both' if env_dir && envpath","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Apply explicit precedence in wrappers (e.g. env_dir wins, envpath nulled) instead of forwarding both","Document each PAL option pair as mutually exclusive in your tool's help text"],"tags":["puppet","pal","argument-error","options"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}