Date::Error ("invalid date") deserializing organizations.get_billing_subscription — API returns proration_date: "" but the Date decoder only handles nil
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 32
- Forks
- 19
- Avg merge
- 19h 27m
- Merged PRs (30d)
- 1
Description
Summary
sdk.organizations.get_billing_subscription raises Date::Error: invalid date while deserializing a successful (HTTP 200) response, because the live API returns "proration_date": "" on subscription items and the generated date decoder only tolerates nil, not an empty string.
Environment
- clerk-sdk-ruby 7.0.0
- Ruby 3.3.1
Reproduction
Call the endpoint for any organization whose billing subscription contains an item with no proration (in our case: an org with an active paid plan plus the upcoming default free plan item):
require "clerk"
Clerk.configure { |c| c.secret_key = ENV["CLERK_SECRET_KEY"] }
Clerk::SDK.new.organizations.get_billing_subscription(organization_id: "org_...")
# => Date::Error: invalid date
The API responds 200 with a payload shaped like:
{
"object": "commerce_subscription",
"status": "active",
"subscription_items": [
{
"object": "commerce_subscription_item",
"status": "active",
"proration_date": "",
"period_start": 1783554837166,
"...": "..."
}
]
}
Root cause
CommerceSubscriptionItem declares the field as an optional ISO date:
# lib/clerk/models/components/commercesubscriptionitem.rb:46
field :proration_date, Crystalline::Nilable.new(::Date),
{ 'format_json': { ..., 'decoder': ::Clerk::Utils.date_from_iso_format(true) } }
but the decoder only short-circuits on nil:
# lib/clerk/utils/utils.rb
def self.date_from_iso_format(optional)
Kernel.lambda do |s|
return nil if optional && s.nil?
return Date.iso8601(s) # Date.iso8601("") raises Date::Error: invalid date
end
end
So any generated model with an optional ::Date field breaks the moment the API emits "" instead of null — which the billing subscription endpoint does for proration_date today. Isolated:
Clerk::Utils.date_from_iso_format(true).call("")
# => Date::Error: invalid date
Suggested fix
Either (or both):
- Treat blank strings as absent in the optional decoder:
return nil if optional && (s.nil? || s.empty?)— presumably a fix in the Speakeasy generation config since this file is generated; or - have the API emit
nullrather than""for absent date fields, matching the OpenAPI schema the SDK is generated from.
As-is, the typed client cannot read this endpoint's real responses at all; we've had to fall back to fetching and parsing the raw JSON.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with lib/clerk/utils/utils.rb and the generated model at lib/clerk/models/components/commercesubscriptionitem.rb; run Clerk::Utils.date_from_iso_format(true).call("") to reproduce the failure. Check the Speakeasy generation configuration or API behavior identified in the issue, then verify organizations.get_billing_subscription can deserialize a subscription item whose proration_date is "" without raising Date::Error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100