{"record":{"id":"707667b4291baa4e","repo":"bblimke/webmock","slug":"times-n-accepts-integers-1-only","errorCode":null,"errorMessage":"times(N) accepts integers >= 1 only","messagePattern":"times\\(N\\) accepts integers >= 1 only","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/webmock/request_stub.rb","lineNumber":99,"sourceCode":"        WebMock::Response.new\n      elsif @responses_sequences.length > 1\n        @responses_sequences.shift if @responses_sequences.first.end?\n        @responses_sequences.first.next_response\n      else\n        @responses_sequences[0].next_response\n      end\n    end\n\n    def has_responses?\n      !@responses_sequences.empty?\n    end\n\n    def then\n      self\n    end\n\n    def times(number)\n      raise \"times(N) accepts integers >= 1 only\" if !number.is_a?(Integer) || number < 1\n      if @responses_sequences.empty?\n        raise \"Invalid WebMock stub declaration.\" +\n          \" times(N) can be declared only after response declaration.\"\n      end\n      @responses_sequences.last.times_to_repeat += number-1\n      self\n    end\n\n    def matches?(request_signature)\n      self.request_pattern.matches?(request_signature)\n    end\n\n    def to_s\n      self.request_pattern.to_s\n    end\n\n    def self.from_request_signature(signature)\n      stub = self.new(signature.method.to_sym, signature.uri.to_s)","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/bblimke/webmock/blob/b187df8827e1f08a1684a8ddc0a5050dbd449c16/lib/webmock/request_stub.rb#L81-L117","documentation":"RequestStub#times(number) makes the most recently declared response sequence repeat number times. It raises a plain RuntimeError unless number is an Integer >= 1 - zero, negative integers, floats, numeric strings and nil are all rejected. The guard keeps the repeat counter from silently no-op'ing when a computed count goes bad.","triggerScenarios":".to(body: 'ok').times(0) or .times(-1); .times(2.0) (float from a calculation); .times('3') (string from ENV or YAML config); .times(nil) (optional variable never set); loop-generated stubs where the computed count hits zero.","commonSituations":"ENV-driven stub counts arriving as strings; Float division or averaging producing non-Integers; refactors that assumed times(0) means never respond; counts taken from let() variables that can be nil.","solutions":["Pass a literal Integer >= 1: .times(3)","Coerce external input at the boundary: .times(Integer(count)) so bad values fail with a clear ArgumentError","If the intent is zero responses, do not register the stub at all, or rely on the default responses instead"],"exampleFix":"// before\nstub_request(:get, 'www.example.com').to(body: 'ok').times(ENV.fetch('STUB_TIMES', 1))\n# ENV values are Strings -> RuntimeError: times(N) accepts integers >= 1 only\n\n// after\nstub_request(:get, 'www.example.com').to(body: 'ok').times(Integer(ENV.fetch('STUB_TIMES', 1)))","handlingStrategy":"validation","validationCode":"count = Integer(ENV.fetch('STUB_TIMES', 1)) # raises early on non-numeric input\nraise ArgumentError, 'times count must be >= 1' unless count >= 1\nstub_request(:get, 'www.example.com').to(body: 'ok').times(count)","typeGuard":"def valid_times_arg?(value)\n  value.is_a?(Integer) && value >= 1\nend","tryCatchPattern":null,"preventionTips":["Coerce with Integer() at the boundary instead of inside the stub chain","Guard loop-computed counts against zero before stubbing","Use fetch with a sensible default rather than || when the value can legitimately be 0 or nil"],"tags":["webmock","ruby","stub","times","argument-validation"],"backgroundTag":"invalid-method-argument","analyzedSha":"b187df8827e1f08a1684a8ddc0a5050dbd449c16","analyzedAt":"2026-08-23T02:55:22.028Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}