{"record":{"id":"ed3ac0aef38e8b44","repo":"github/scientist","slug":"experiment-name-already-has-name-behavior","errorCode":null,"errorMessage":"#{experiment.name} already has #{name} behavior","messagePattern":"#(.+?) already has #(.+?) behavior","errorType":"exception","errorClass":"Scientist::BehaviorNotUnique","httpStatus":null,"severity":"error","filePath":"lib/scientist/experiment.rb","lineNumber":296,"sourceCode":"    return false\n  end\n\n  # Internal: determine whether or not an experiment should run.\n  #\n  # Rescues and reports exceptions in the enabled method if they occur.\n  def should_experiment_run?\n    behaviors.size > 1 && enabled? && run_if_block_allows?\n  rescue StandardError => ex\n    raised :enabled, ex\n    return false\n  end\n\n  # Register a named behavior for this experiment, default \"candidate\".\n  def try(name = nil, &block)\n    name = (name || \"candidate\").to_s\n\n    if behaviors.include?(name)\n      raise Scientist::BehaviorNotUnique.new(self, name)\n    end\n\n    behaviors[name] = block\n  end\n\n  # Register the control behavior for this experiment.\n  def use(&block)\n    try \"control\", &block\n  end\n\n  # Whether or not to raise a mismatch error when a mismatch occurs.\n  def raise_on_mismatches?\n    if raise_on_mismatches.nil?\n      self.class.raise_on_mismatches?\n    else\n      !!raise_on_mismatches\n    end\n  end","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/github/scientist/blob/504a396e987f655a21c6bf2ed57935aadaa40859/lib/scientist/experiment.rb#L278-L314","documentation":"Scientist::BehaviorNotUnique is raised by Experiment#try when a behavior with the same name has already been registered on the experiment. Each experiment instance allows exactly one block per behavior name (\"control\" for `use`, \"candidate\" by default for `try`); duplicate registration raises instead of silently overwriting.","triggerScenarios":"Calling `experiment.try { ... }` twice without names (both register \"candidate\"); calling `experiment.try(:x) { }` twice; calling `use` twice (both register \"control\"); re-running a behavior-registration helper on the same experiment instance; named `try` calls that collide with an existing name.","commonSituations":"Loops or helper methods that register candidates and get invoked twice on the same experiment object; duplicate `use` calls from copy-paste; memoization mistakes that re-run registration code; framework integrations registering a behavior in both a DSL callback and setup code.","solutions":["Use distinct names for each candidate: `try(\"candidate_a\") { }`, `try(\"candidate_b\") { }`.","Ensure each registration method is called at most once per name per instance; guard with `behaviors.include?(name)` if unsure.","Create a new experiment instance if you need to re-register the same-named behavior.","Fix the code path that invokes the registration helper twice (e.g. a loop not creating fresh experiments per iteration)."],"exampleFix":"# before\nexp.try { candidate_a }  # registers \"candidate\"\nexp.try { candidate_b }  # BehaviorNotUnique\n\n# after\nexp.try(\"candidate_a\") { candidate_a }\nexp.try(\"candidate_b\") { candidate_b }\nexp.run","handlingStrategy":"validation","validationCode":"raise \"duplicate candidate #{name}\" if experiment.send(:behaviors).key?(name.to_s)\nexperiment.try(name) { block }","typeGuard":"def can_register?(exp, name = \"candidate\")\n  !exp.send(:behaviors).key?(name.to_s)\nend","tryCatchPattern":"begin\n  experiment.try(name) { candidate_block }\nrescue Scientist::BehaviorNotUnique\n  logger.warn(\"candidate #{name} already registered; skipping\")\nend","preventionTips":["Give every `try` call an explicit unique name instead of relying on the default \"candidate\".","Call `use`/`try` exactly once per name; build registration in one place, not in loops over the same instance.","Create a fresh experiment object per registration cycle instead of reusing one.","In helpers, check `behaviors.include?(name)` before registering."],"tags":["ruby","scientist","duplicate-registration","behavior-not-unique"],"backgroundTag":"file-already-exists","analyzedSha":"504a396e987f655a21c6bf2ed57935aadaa40859","analyzedAt":"2026-09-13T22:55:19.059Z","contentChangedAt":"2026-09-13T22:55:19.059Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}