Versions
google-cloud-storage 1.62.0, google-cloud-bigquery 1.64.0
- Ruby 3.4
Problem
The wrapper gems pass keyword arguments to their generated google-apis-* companions that older releases of those companions do not accept, but the gemspec floors were never raised to match. Bundler therefore resolves a bundle that is entirely valid by its own rules and that fails at runtime on the first call.
google-cloud-storage 1.62.0 declares:
google-apis-storage_v1 >= 0.42
but Google::Cloud::Storage::Service#list_files passes filter: to Google::Apis::StorageV1::StorageService#list_objects, and #list_buckets passes return_partial_success:. Comparing the wrapper's call sites against the generated
signatures release by release:
list_objects(filter:) is first accepted in google-apis-storage_v1 0.54.0
list_buckets(return_partial_success:) is first accepted in 0.57.0
So the real floor for google-cloud-storage 1.58.0 through 1.62.0 is google-apis-storage_v1 >= 0.57.0 — fifteen minor versions above what the gemspec asks for.
The same shape exists in BigQuery. google-cloud-bigquery 1.64.0 declares google-apis-bigquery_v2 ~> 0.71, but passes update_mode: to patch_dataset, which google-apis-bigquery_v2 first accepts in 0.88.0.
Reproduction
# Gemfile
gem "google-cloud-storage", "1.62.0"
gem "google-apis-storage_v1", "0.50.0" # satisfies the declared >= 0.42
require "google/cloud/storage"
Google::Cloud::Storage.anonymous.bucket("any-bucket", skip_lookup: true).files
ArgumentError: unknown keyword: :filter
google-apis-storage_v1-0.50.0/lib/google/apis/storage_v1/service.rb:2969:in 'list_objects'
google-cloud-storage-1.62.0/lib/google/cloud/storage/service.rb:377:in 'list_files'
google-cloud-storage-1.62.0/lib/google/cloud/storage/bucket.rb:1663:in 'files'
Why it is easy to hit
bundle update google-cloud-storage --conservative, or any resolution that holds shared
dependencies back, moves the wrapper and leaves the generated gem where it is. The result
installs cleanly, passes a test suite that stubs at the wrapper boundary, and fails the
first time an object listing runs for real.
Suggested fix
- Raise the declared floors to what the wrappers actually require:
google-apis-storage_v1 >= 0.57.0 and google-apis-bigquery_v2 >= 0.88.0.
- Consider a release-time check that compares the keyword arguments at the wrapper's
call sites against the signatures in the minimum supported companion release, so the
floor cannot silently drift again the next time the generated client gains a parameter.
Versions
google-cloud-storage1.62.0,google-cloud-bigquery1.64.0Problem
The wrapper gems pass keyword arguments to their generated
google-apis-*companions that older releases of those companions do not accept, but the gemspec floors were never raised to match. Bundler therefore resolves a bundle that is entirely valid by its own rules and that fails at runtime on the first call.google-cloud-storage1.62.0 declares:but
Google::Cloud::Storage::Service#list_filespassesfilter:toGoogle::Apis::StorageV1::StorageService#list_objects, and#list_bucketspassesreturn_partial_success:. Comparing the wrapper's call sites against the generatedsignatures release by release:
list_objects(filter:)is first accepted ingoogle-apis-storage_v10.54.0list_buckets(return_partial_success:)is first accepted in 0.57.0So the real floor for
google-cloud-storage1.58.0 through 1.62.0 isgoogle-apis-storage_v1 >= 0.57.0— fifteen minor versions above what the gemspec asks for.The same shape exists in BigQuery.
google-cloud-bigquery1.64.0 declaresgoogle-apis-bigquery_v2 ~> 0.71, but passesupdate_mode:topatch_dataset, whichgoogle-apis-bigquery_v2first accepts in 0.88.0.Reproduction
Why it is easy to hit
bundle update google-cloud-storage --conservative, or any resolution that holds shareddependencies back, moves the wrapper and leaves the generated gem where it is. The result
installs cleanly, passes a test suite that stubs at the wrapper boundary, and fails the
first time an object listing runs for real.
Suggested fix
google-apis-storage_v1 >= 0.57.0andgoogle-apis-bigquery_v2 >= 0.88.0.call sites against the signatures in the minimum supported companion release, so the
floor cannot silently drift again the next time the generated client gains a parameter.