vcr/vcr · error · ArgumentError
`VCR.use_cassette` requires a block. If you cannot wrap your
Error message
`VCR.use_cassette` requires a block. If you cannot wrap your code in a block, use `VCR.insert_cassette` / `VCR.eject_cassette` instead.
What it means
VCR.use_cassette is a block-scoped API: it inserts a cassette, runs the block, and ejects in an ensure clause. Called without a block it raises ArgumentError pointing you to VCR.insert_cassette / VCR.eject_cassette for non-block use cases (lib/vcr.rb:186).
Source
Thrown at lib/vcr.rb:186
# block, and ejects the cassette.
#
# @example
# VCR.use_cassette('twitter', record: :new_episodes) do
# # make an HTTP request
# end
#
# @param (see #insert_cassette)
# @option (see #insert_cassette)
# @yield Block to run while this cassette is in use.
# @yieldparam cassette [(optional) VCR::Cassette] the cassette that has
# been inserted.
# @raise (see #insert_cassette)
# @return [void]
# @see #insert_cassette
# @see #eject_cassette
def use_cassette(name, options = {}, &block)
unless block
raise ArgumentError, "`VCR.use_cassette` requires a block. " +
"If you cannot wrap your code in a block, use " +
"`VCR.insert_cassette` / `VCR.eject_cassette` instead."
end
cassette = insert_cassette(name, options)
begin
call_block(block, cassette)
rescue StandardError
cassette.run_failed!
raise
ensure
eject_cassette
end
end
# Inserts multiple cassettes the given names
#View on GitHub (pinned to a747bb6478)
Solutions
- Add the block: VCR.use_cassette('api') do ... end
- If the code cannot be wrapped in a block (e.g. cassette must span helper methods or setup/teardown), switch to the explicit API: cassette = VCR.insert_cassette('api') ... VCR.eject_cassette
- If a helper wraps use_cassette, forward the caller's block with &block
Example fix
# before
VCR.use_cassette('api')
client.get('/repos') # ArgumentError, and never recorded
# after
VCR.use_cassette('api') do
client.get('/repos')
end
# non-block alternative
cassette = VCR.insert_cassette('api')
client.get('/repos')
VCR.eject_cassette Defensive patterns
Strategy: validation
Validate before calling
def with_cassette(name, options = {}, &block)
raise ArgumentError, 'a block is required' unless block
VCR.use_cassette(name, options, &block)
end Prevention
- Treat use_cassette as strictly block-scoped; for setup/teardown flows use insert_cassette/eject_cassette pairs in before/after hooks
- When wrapping use_cassette in helpers, always accept and forward &block
When it happens
Trigger: VCR.use_cassette('api') with no do...end (forgotten or removed in a refactor); expecting the cassette to stay active for the rest of the file; passing a lambda in the options hash instead of as the actual block, e.g. VCR.use_cassette('api', &nil) or VCR.use_cassette('api', block_as_option: proc { }); multiline calls where the do keyword was accidentally deleted.
Common situations: Refactors that extracted the body into a helper without forwarding the block (&block); developers wanting a file-wide cassette; copy-paste from examples that used insert/eject style; rspec metadata-based cassette usage mixed with manual calls.
Related errors
- You must provide a block to set the cassette options
- There is already a cassette with the same name (#{name}). Y
- VCR is turned off. You must turn it on before you can inser
- You passed some invalid options: #{invalid_options.inspect}
- You passed the following invalid options to VCR::Cassette.ne
AI-assisted analysis of vcr/vcr@a747bb6478 (2026-08-21).
Data as JSON: /api/errors/770adab9e0c2ed17.
Report an issue: GitHub.