bkeepers/dotenv · error · ArgumentError
Invalid value for overwrite: #{overwrite.inspect}
Error message
Invalid value for overwrite: #{overwrite.inspect} What it means
Dotenv.update accepts an `overwrite:` keyword that must be exactly `true`, `false`, or the symbol `:warn`; the case statement's else branch raises ArgumentError for any other value. dotenv deliberately does no type coercion, so truthy strings or integers are rejected instead of being interpreted. The raised message interpolates the offending value via inspect so you can immediately see what was passed.
Source
Thrown at lib/dotenv.rb:110
end
# Update `ENV` with the given hash of keys and values
#
# @param env [Hash] Hash of keys and values to set in `ENV`
# @param overwrite [Boolean|:warn] Overwrite existing `ENV` values
def update(env = {}, overwrite: false)
instrument(:update) do |payload|
diff = payload[:diff] = Dotenv::Diff.new do
ENV.update(env.transform_keys(&:to_s)) do |key, old_value, new_value|
# This block is called when a key exists. Return the new value if overwrite is true.
case overwrite
when :warn
# not printing the value since that could be a secret
warn "Warning: dotenv not overwriting ENV[#{key.inspect}]"
old_value
when true then new_value
when false then old_value
else raise ArgumentError, "Invalid value for overwrite: #{overwrite.inspect}"
end
end
end
diff.env
end
end
# Modify `ENV` for the block and restore it to its previous state afterwards.
#
# Note that the block is synchronized to prevent concurrent modifications to `ENV`,
# so multiple threads will be executed serially.
#
# @param env [Hash] Hash of keys and values to set in `ENV`
def modify(env = {}, &block)
SEMAPHORE.synchronize do
diff = Dotenv::Diff.new
update(env, overwrite: true)
block.callView on GitHub (pinned to 34156bf400)
Solutions
- Pass a real boolean or the symbol :warn: `overwrite: true`, `overwrite: false`, or `overwrite: :warn`
- Coerce external input before the call, e.g. `overwrite: %w[true 1 yes].include?(str.downcase)` or ActiveModel::Type::Boolean in Rails
- Use `opts.fetch(:overwrite, false)` instead of `opts[:overwrite]` so an absent key defaults to false rather than nil
Example fix
# before Dotenv.update(env, overwrite: ENV["DOTENV_OVERWRITE"]) # "true" (String) -> ArgumentError # after Dotenv.update(env, overwrite: %w[true 1 yes].include?(ENV["DOTENV_OVERWRITE"].to_s.downcase))
Defensive patterns
Strategy: validation
Validate before calling
overwrite = opts.fetch(:overwrite, false) raise ArgumentError, "overwrite must be true, false, or :warn" unless [true, false, :warn].include?(overwrite) Dotenv.update(env, overwrite: overwrite)
Type guard
# Ruby: value-level guard for the overwrite flag def valid_overwrite?(value) [true, false, :warn].include?(value) end
Try / catch
begin Dotenv.update(env, overwrite: flag) rescue ArgumentError flag = false # safe default, then retry with a known-good value retry end
Prevention
- Never forward raw strings or nil from ENV/ARGV/YAML into keyword flags — coerce at the boundary
- Use opts.fetch(:key, default) for optional flags so nil never reaches the API
- Whitelist-validate enum-like options (true/false/:warn) as close to the caller as possible
When it happens
Trigger: `Dotenv.update({"KEY" => "v"}, overwrite: "true")` (String from ENV/ARGV/YAML), `overwrite: 1`, or `overwrite: nil` from `overwrite: opts[:overwrite]` when the options hash lacks the key — anything not literally true, false, or :warn.
Common situations: Reading the flag from `ENV["OVERWRITE"]` or CLI args and passing the string straight through; forwarding an optional options hash where a missing key yields nil; booleans serialized as strings in YAML/JSON config files.
Related errors
AI-assisted analysis of bkeepers/dotenv@34156bf400 (2026-08-21).
Data as JSON: /api/errors/4dc5331867ec3fea.
Report an issue: GitHub.