ruby/ruby · error · ArgumentError
mem_size must be a Integer
Error message
mem_size must be a Integer
What it means
RubyVM::YJIT.enable validates the mem_size keyword (executable code area size, in MB) and requires a true Integer. Strings ('128') and Floats — including whole-valued ones like 64.0 — fail mem_size.is_a?(Integer) and raise ArgumentError. The same value must then be within 1..2048, but that is a separate check.
Source
Thrown at yjit.rb:57
#
# * `stats`:
# * `false`: Don't enable stats.
# * `true`: Enable stats. Print stats at exit.
# * `:quiet`: Enable stats. Do not print stats at exit.
# * `log`:
# * `false`: Don't enable the log.
# * `true`: Enable the log. Print log at exit.
# * `:quiet`: Enable the log. Do not print log at exit.
def self.enable(stats: false, log: false, mem_size: nil, call_threshold: nil)
return false if enabled?
if Primitive.cexpr! 'RBOOL(rb_zjit_enabled_p)'
warn("Only one JIT can be enabled at the same time.")
return false
end
if mem_size
raise ArgumentError, "mem_size must be a Integer" unless mem_size.is_a?(Integer)
raise ArgumentError, "mem_size must be between 1 and 2048 MB" unless (1..2048).include?(mem_size)
end
if call_threshold
raise ArgumentError, "call_threshold must be a Integer" unless call_threshold.is_a?(Integer)
raise ArgumentError, "call_threshold must be a positive integer" unless call_threshold.positive?
end
at_exit { print_and_dump_stats } if stats
Primitive.rb_yjit_enable(stats, stats != :quiet, log, log != :quiet, mem_size, call_threshold)
end
# If --yjit-trace-exits is enabled parse the hashes from
# Primitive.rb_yjit_get_exit_locations into a format readable
# by Stackprof. This will allow us to find the exact location of a
# side exit in YJIT based on the instruction that is exiting.
def self.exit_locations # :nodoc:
return unless trace_exit_locations_enabled?View on GitHub (pinned to 0e5b888e1c)
Solutions
- Coerce at the boundary: mem_size: value&.to_i for trusted config, or Integer(value) for strict parsing
- Pass an Integer literal within the documented 1..2048 range
- Validate config types once at load time (ENV schema, dry-validation) so YJIT.enable never sees strings
Example fix
# before RubyVM::YJIT.enable(mem_size: ENV['YJIT_MEM_SIZE']) # String from ENV -> ArgumentError # after RubyVM::YJIT.enable(mem_size: ENV['YJIT_MEM_SIZE']&.to_i) # nil or Integer
Defensive patterns
Strategy: type-guard
Validate before calling
mem = config.fetch(:yjit_mem_size, nil) mem = Integer(mem) if mem.is_a?(String) # strict cast; raises early on garbage RubyVM::YJIT.enable(mem_size: mem) if mem.nil? || mem.is_a?(Integer)
Type guard
# Exact check YJIT itself performs; note Float 64.0 is rejected by design def yjit_integer?(v) v.is_a?(Integer) end
Try / catch
begin
RubyVM::YJIT.enable(mem_size: mem)
rescue ArgumentError => e
warn "YJIT config rejected (#{e.message}); enabling with defaults"
RubyVM::YJIT.enable
end Prevention
- Convert ENV and YAML values with to_i (or strict Integer()) at the config boundary
- Remember Floats are rejected even when whole: use Integer literals
- Add a config-loading spec that asserts types before they reach YJIT.enable
When it happens
Trigger: RubyVM::YJIT.enable(mem_size: '128') with a String from ENV or YAML config; mem_size: 64.0 produced by a Float computation or JSON number parsing; any truthy non-Integer (nil is allowed and skips validation).
Common situations: Reading mem_size from ENV variables or YAML without to_i; arithmetic that produced Floats (64.0/1); JSON configs whose numbers parse as Float.
Related errors
- mem_size must be between 1 and 2048 MB
- call_threshold must be a Integer
- should be Ractor::Port or Ractor
- call_threshold must be a positive integer
- --yjit-trace-exits must be enabled to use dump_exit_location
AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21).
Data as JSON: /api/errors/7b087e32b4cfe1f5.
Report an issue: GitHub.