Skip to content

fix: coerce parsed arg values to match declared types#239

Merged
pi0 merged 1 commit intomainfrom
fix/coerce
Mar 16, 2026
Merged

fix: coerce parsed arg values to match declared types#239
pi0 merged 1 commit intomainfrom
fix/coerce

Conversation

@danielroe
Copy link
Copy Markdown
Member

@danielroe danielroe commented Mar 16, 2026

node:util.parseArgs with strict:false can return wrong types:

  • boolean args with --flag=true/--flag=false return strings 'true'/'false'
  • string args without a value (--flag) return boolean true instead of ''

Summary by CodeRabbit

  • New Features

    • Improved argument parsing with type-aware value coercion for boolean and string options, enabling proper handling of explicit true/false values and string arguments without values.
  • Tests

    • Added test coverage for boolean and string argument coercion scenarios.

@danielroe danielroe requested a review from pi0 March 16, 2026 12:37
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

The argument parser now applies type-aware value coercion during parsing. A new isStringType() helper determines if an option is a string type. When assigning parsed values, boolean options coerce string values using strict comparison against "false", while string options coerce boolean values to empty strings. Existing alias resolution and propagation behavior is preserved.

Changes

Cohort / File(s) Summary
Parser Implementation
src/_parser.ts
Added isStringType() helper function and enhanced value coercion logic to handle type conversion between string and boolean values based on option type during assignment.
Argument Parsing Tests
test/args.test.ts
New tests verify coercion of boolean arguments from string values (--force=true, --force=false, --install=false) and string arguments without values returning empty strings.
Parser Suite Tests
test/parser.test.ts
Three new tests added to parseRawArgs suite covering coercion of boolean flag arguments with explicit true/false values and string arguments without values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops through types with care,
Coercing booleans here and there,
"true" and "false" now find their place,
As strings transform with gentle grace,
The parser's logic, swift and bright,
Makes argument handling just right! 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: introducing type coercion for parsed argument values to match their declared types, which directly addresses the reported issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/coerce
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

Migrating from UI to YAML configuration.

Use the @coderabbitai configuration command in a PR comment to get a dump of all your UI settings in YAML format. You can then edit this YAML file and upload it to the root of your repository to configure CodeRabbit programmatically.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/args.test.ts (1)

128-132: Add one alias-path assertion for empty-string coercion.

You’re testing --nightly directly; adding an alias case (e.g. -n) would directly exercise the alias-aware path used in parser coercion.

Proposed test addition
   it("should return empty string for string arg without value", () => {
     const parsed = parseArgs(["--nightly"], { nightly: { type: "string" } });
     expect(parsed.nightly).toBe("");
     expect(typeof parsed.nightly).toBe("string");
   });
+
+  it("should return empty string for aliased string arg without value", () => {
+    const parsed = parseArgs(["-n"], { nightly: { type: "string", alias: "n" } });
+    expect(parsed.nightly).toBe("");
+    expect(parsed.n).toBe("");
+    expect(typeof parsed.nightly).toBe("string");
+  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/args.test.ts` around lines 128 - 132, Add an additional assertion in the
"should return empty string for string arg without value" test to exercise the
alias-aware path: call parseArgs with the alias form (e.g., ["-n"]) using the
same options ({ nightly: { type: "string", alias: "n" } } or ensure alias
mapping is present) and assert that parsed.nightly === "" and typeof
parsed.nightly === "string" so the parser's alias coercion branch (parseArgs) is
covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/_parser.ts`:
- Around line 154-155: The boolean string coercion currently only checks value
!== "false" which misclassifies inputs like "False" or " false "; update the
branch in src/_parser.ts where type === "boolean" && typeof value === "string"
to normalize the string first (e.g., value.trim().toLowerCase()) and then
compare to "false" before setting coerced; ensure you reference the variables
type, value, and coerced so the normalized comparison is used when assigning
coerced.

---

Nitpick comments:
In `@test/args.test.ts`:
- Around line 128-132: Add an additional assertion in the "should return empty
string for string arg without value" test to exercise the alias-aware path: call
parseArgs with the alias form (e.g., ["-n"]) using the same options ({ nightly:
{ type: "string", alias: "n" } } or ensure alias mapping is present) and assert
that parsed.nightly === "" and typeof parsed.nightly === "string" so the
parser's alias coercion branch (parseArgs) is covered.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9aa0cebf-84e5-460b-81d3-fe8df3fbcd8d

📥 Commits

Reviewing files that changed from the base of the PR and between ea428c7 and b4e8e7d.

📒 Files selected for processing (3)
  • src/_parser.ts
  • test/args.test.ts
  • test/parser.test.ts

Comment on lines +154 to +155
if (type === "boolean" && typeof value === "string") {
coerced = value !== "false";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Normalize boolean string values before false-check.

Line 155 currently treats only exact "false" as false. Inputs like --flag=False or --flag=" false " will be coerced to true.

Proposed fix
-    if (type === "boolean" && typeof value === "string") {
-      coerced = value !== "false";
+    if (type === "boolean" && typeof value === "string") {
+      const normalized = value.trim().toLowerCase();
+      coerced = normalized !== "false";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (type === "boolean" && typeof value === "string") {
coerced = value !== "false";
if (type === "boolean" && typeof value === "string") {
const normalized = value.trim().toLowerCase();
coerced = normalized !== "false";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/_parser.ts` around lines 154 - 155, The boolean string coercion currently
only checks value !== "false" which misclassifies inputs like "False" or " false
"; update the branch in src/_parser.ts where type === "boolean" && typeof value
=== "string" to normalize the string first (e.g., value.trim().toLowerCase())
and then compare to "false" before setting coerced; ensure you reference the
variables type, value, and coerced so the normalized comparison is used when
assigning coerced.

@pi0 pi0 merged commit e6fa9ac into main Mar 16, 2026
3 checks passed
@pi0 pi0 deleted the fix/coerce branch March 16, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants