{"record":{"id":"938d567015514dd4","repo":"puppetlabs/puppet","slug":"klass-cannot-be-added-to-a-timestamp","errorCode":null,"errorMessage":"%{klass} cannot be added to a Timestamp","messagePattern":"%(.+?) cannot be added to a Timestamp","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/time/timestamp.rb","lineNumber":135,"sourceCode":"    from_time(parsed_time)\n  end\n\n  undef_method :-@, :+@, :div, :fdiv, :abs, :abs2, :magnitude # does not make sense on a Timestamp\n  if method_defined?(:negative?)\n    undef_method :negative?, :positive?\n  end\n  if method_defined?(:%)\n    undef_method :%, :modulo, :divmod\n  end\n\n  def +(o)\n    case o\n    when Timespan\n      Timestamp.new(@nsecs + o.nsecs)\n    when Integer, Float\n      Timestamp.new(@nsecs + (o * NSECS_PER_SEC).to_i)\n    else\n      raise ArgumentError, _(\"%{klass} cannot be added to a Timestamp\") % { klass: a_an_uc(o) }\n    end\n  end\n\n  def -(o)\n    case o\n    when Timestamp\n      # Diff between two timestamps is a timespan\n      Timespan.new(@nsecs - o.nsecs)\n    when Timespan\n      Timestamp.new(@nsecs - o.nsecs)\n    when Integer, Float\n      # Subtract seconds\n      Timestamp.new(@nsecs - (o * NSECS_PER_SEC).to_i)\n    else\n      raise ArgumentError, _(\"%{klass} cannot be subtracted from a Timestamp\") % { klass: a_an_uc(o) }\n    end\n  end\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/time/timestamp.rb#L117-L153","documentation":"Timestamp#+ accepts only a Timespan or an Integer/Float (seconds) - adding two absolute points in time is undefined, so Timestamp operands are rejected too. Anything else (including Timestamp, String, nil) raises '%{klass} cannot be added to a Timestamp'. For contrast, Timestamp - Timestamp IS legal and yields a Timespan.","triggerScenarios":"ts + ts2 (both Timestamps), ts + '3600', ts + nil, ts + array. Most common genuine mistake: ts1 + ts2 where the developer wanted the difference (ts2 - ts1).","commonSituations":"Adding an expiry read from two different sources that both turned out to be Timestamps; Hiera-provided seconds arriving as String; nil from optional parameters; adding Puppet Sensitive or Decimal wrappers.","solutions":["If you meant 'difference between two timestamps', use subtraction: ts2 - ts1 returns a Timespan","If you meant 'timestamp plus duration', ensure the right side is a Timespan or numeric seconds: ts + Timespan(0, 3600)","Convert string seconds with .to_i / Float()","nil-guard optional durations before the expression"],"exampleFix":"// before\nelapsed = finished_at + started_at   # both Timestamps -> raise\n\n// after\nelapsed = finished_at - started_at    # Timespan (the intended computation)","handlingStrategy":"type-guard","validationCode":"ok = o.is_a?(Puppet::Pops::Time::Timespan) || o.is_a?(Integer) || o.is_a?(Float)\nraise ArgumentError, \"cannot add #{o.class} to Timestamp\" unless ok\nts + o","typeGuard":"def timestamp_addable?(o)\n  o.is_a?(Puppet::Pops::Time::Timespan) || o.is_a?(Integer) || o.is_a?(Float)\nend","tryCatchPattern":"begin\n  ts + o\nrescue ArgumentError => e\n  raise DataError, \"#{o.class} not addable to Timestamp (did you mean subtraction for a difference?)\"\nend","preventionTips":["Timestamp + Timestamp is always wrong - use subtraction for differences","Coerce String seconds with Integer()/Float() at boundaries","nil-check optional durations before arithmetic"],"tags":["puppet","timestamp","arithmetic","argument-error","type-mismatch"],"backgroundTag":"invalid-operand-type","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}