Fix empty-string plan mismatch between Ruby and Node (#2452) - #2566
Conversation
In Ruby "" is truthy so `check_plan` correctly rejects it as invalid, but in Node "" is falsy so `checkPlan` incorrectly treated it as absent (valid). Use `plan == null` instead of `!plan` so only null/undefined are treated as absent, aligning Node behavior with Ruby. Closes #2452 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThis PR aligns Node.js plan validation behavior with Ruby's by treating empty string plans as invalid. Changes modify the falsy check in Node's validation logic to an explicit null check, ensuring empty strings are validated against the allowed plans list rather than treated as absent. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR fixes a cross-runtime behaviour mismatch where Key changes:
Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[checkPlan / check_plan called] --> B{plan == null\nor plan is nil?}
B -- "yes (null / undefined / nil / absent)" --> C["return 'valid'\n(backwards compat)"]
B -- "no (any other value\nincluding empty string)" --> D{VALID_PLANS\nincludes plan?}
D -- yes --> E["return 'valid'"]
D -- no --> F["return 'invalid'\n⬅ empty string now lands here"]
style F fill:#f96,color:#000
style C fill:#6c6,color:#000
style E fill:#6c6,color:#000
Last reviewed commit: b7ea002 |
Code ReviewThis is a well-targeted fix for the Ruby/Node truthiness mismatch on empty-string plan values. What's correctRoot cause correctly identified: Ruby treats
Backwards compatibility preserved: Minor observationsIntentional inconsistency in Breaking behavior change for Ruby spec is additive documentation: The new spec in SummaryClean, minimal fix — the two changed lines in |
| function checkPlan(decodedData: LicenseData): LicenseStatus { | ||
| const { plan } = decodedData; | ||
| if (!plan) { | ||
| if (plan == null) { |
There was a problem hiding this comment.
Good fix. The key insight is the Ruby/JS truthiness difference:
- Ruby:
unless planonly short-circuits fornil/false—""is truthy and falls through to theVALID_PLANS.include?check →:invalid - JS before:
!planshort-circuited for""(falsy) →'valid'❌ - JS after:
plan == nullonly catchesnull/undefined→""falls through →'invalid'✓
plan == null (loose equality) is the idiomatic JS equivalent of Ruby's unless plan.nil?.
| end | ||
|
|
||
| it "returns :invalid (empty string is not a valid plan)" do | ||
| expect(described_class.license_status).to eq(:invalid) |
There was a problem hiding this comment.
Good addition. This spec pins Ruby's existing (correct) behavior and guards against a future refactor accidentally introducing the same !plan-style falsy check in Ruby. Worth noting in the spec description that this is already-correct behavior being documented, not a behavior change on the Ruby side.
size-limit report 📦
|
Add entries for user-visible changes since v16.4.0.rc.6: - #2539: env-var-driven ports in Procfile templates - #2417: rspack generator config path fix - #2419: precompile hook load-based execution fix - #2577: create-react-on-rails-app validation improvements - #2416: StreamResponse status fallback fix (Pro) - #2566: empty-string license plan mismatch fix (Pro) - Updated #2561 entry to include #2568 contributor credit Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Add changelog entries for 6 user-visible PRs merged since v16.4.0.rc.6 that were missing from `[Unreleased]` - Update existing #2561 entry to include #2568 contributor credit ### New entries added | Section | PR | Description | |---|---|---| | Added | #2539 | Environment-variable-driven ports in Procfile templates | | Fixed | #2417 | Rspack generator config path fix | | Fixed | #2419 | Precompile hook load-based execution fix | | Fixed | #2577 | `create-react-on-rails-app` validation improvements | | Pro Fixed | #2416 | StreamResponse status fallback fix | | Pro Fixed | #2566 | Empty-string license plan mismatch fix | ### Skipped PRs (not user-visible) Docs (#2406, #2414, #2479, #2494, #2518, #2537, #2544), CI/internal (#2533, #2547, #2555, #2557, #2558, #2564), dependabot (#2387, #2541), dev dependencies (#2559, #2569, #2573). ## Test plan - [ ] Verify changelog formatting matches existing entries - [ ] Verify all user-visible PRs since v16.4.0.rc.6 are covered 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Documentation-only changelog updates with no runtime or build behavior changes. > > **Overview** > Updates `CHANGELOG.md`’s **[Unreleased]** section to include previously missing user-facing entries: Procfile templates now support env-driven ports, several generator/`bin/dev` precompile-hook and rspack-path fixes are documented, and `create-react-on-rails-app` validation improvements are noted. > > Also adds two Pro fix entries (StreamResponse status fallback and license plan empty-string validation) and updates the existing `bin/dev` precompile-hook entry to credit an additional PR/contributor. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e75d2b5. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
checkPlanwith Rubycheck_plansoplan: ""yields:invalidin both runtimesplan == nullinstead of!planin Node — onlynull/undefinedcount as absent (backwards compat), while""falls through to the VALID_PLANS checkplan: ""to document existing behaviorTest plan
licenseValidator.test.tspasses (empty string now expects'invalid')license_validator_spec.rbpasses (60 examples, 0 failures, including new empty-string test)nullandundefinedplan still return'valid'(backwards compat preserved)Closes #2452
🤖 Generated with Claude Code
Summary by CodeRabbit