Skip to content

Conversation

@Sandijigs
Copy link

Motivation

Duplicating single-value CLI flags (like --checkpointSyncUrl)
by accident gets silently turned into an array, leading to
confusing errors later on. This PR catches duplicate single-value flags early and shows
users exactly what went wrong, instead of letting the error
happen later with a confusing message.

Description

This PR implements validation middleware to detect and
reject duplicate single-value CLI flags with clear error
messages.
Changes made:

 - Added `validateNoDuplicateSingleValueFlags()` function in
  `/packages/utils/src/command.ts` to check if single-value
 options (type: `string`, `number`, `boolean`) have received
  multiple values

 - Integrated validation as middleware in
 `registerCommandToYargs()` to run before command handler
 execution

 - Created test suite in
 `/packages/utils/test/unit/command.test.ts` with 10 test
 cases covering various scenarios

 - Validation explicitly skips array-type options to
 preserve their multi-value functionality
Screenshot 2025-10-24 at 12 54 49 am

Closes #8178

Steps to test or reproduce

  1. Run the new unit tests:

yarn vitest run packages/utils/test/unit/command.test.ts
Should show 10 tests passing.

  1. Test with actual CLI (reproduces the original bug):bash ./lodestar beacon --checkpointSyncUrl https://example1.com --checkpointSyncUrl https://example2.com Before fix: Gets confusing error later
    ("HttpClient.urls[0] is empty")
    After fix: Gets immediate clear error: Option
    --checkpointSyncUrl' is a single-value flag but was provided multiple times

  2. Test that array flags still work: ./lodestar beacon --bootnodes=node1 --bootnodes=node2

@Sandijigs Sandijigs requested a review from a team as a code owner October 24, 2025 01:14
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Sandijigs, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where duplicating single-value Command Line Interface (CLI) flags would silently convert them into arrays, leading to confusing and delayed errors. The changes introduce a robust validation mechanism that proactively detects and rejects such duplicate flags, providing immediate and clear feedback to the user. This significantly improves the user experience by preventing obscure runtime errors related to CLI argument parsing.

Highlights

  • New Validation Function: Introduced validateNoDuplicateSingleValueFlags() in packages/utils/src/command.ts to identify when single-value CLI options (string, number, boolean) are provided multiple times.
  • Middleware Integration: The new validation function is integrated as middleware within registerCommandToYargs(), ensuring that duplicate single-value flags are caught and rejected with clear error messages before command execution.
  • Comprehensive Test Suite: A new test file, packages/utils/test/unit/command.test.ts, has been added with 10 unit tests to cover various scenarios, including successful single-value and array flag parsing, and error handling for duplicated single-value flags.
  • Array Flag Exemption: The validation explicitly bypasses array-type options, preserving their intended multi-value functionality.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a validation middleware to prevent duplicate single-value CLI flags, which is a great improvement for user experience. The implementation in command.ts is clean and effective, and the new test suite in command.test.ts is comprehensive. I have a few minor suggestions to improve code style in the error message construction and to make the test assertions more efficient.

Comment on lines +67 to +70
throw new Error(
`Option '--${optionName}' is a single-value flag but was provided multiple times. ` +
`Received values: [${value.join(", ")}]. Please provide only one value.`
);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For better readability and to avoid string concatenation, you can use a single template literal for the error message.

      throw new Error(
        `Option '--${optionName}' is a single-value flag but was provided multiple times. Received values: [${value.join(", ")]. Please provide only one value.`
      );

Comment on lines +116 to +120
expect(() => parser.parseSync()).toThrow(
"Option '--url' is a single-value flag but was provided multiple times"
);
expect(() => parser.parseSync()).toThrow("https://example1.com");
expect(() => parser.parseSync()).toThrow("https://example2.com");
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Calling parser.parseSync() multiple times is inefficient and can be brittle if the function has side effects. It's better to perform a single parse and check the thrown error message for all required substrings. You can combine these assertions into a single toThrow with a more specific error message.

Suggested change
expect(() => parser.parseSync()).toThrow(
"Option '--url' is a single-value flag but was provided multiple times"
);
expect(() => parser.parseSync()).toThrow("https://example1.com");
expect(() => parser.parseSync()).toThrow("https://example2.com");
expect(() => parser.parseSync()).toThrow(
"Option '--url' is a single-value flag but was provided multiple times. Received values: [https://example1.com, https://example2.com]. Please provide only one value."
);

Comment on lines +267 to +272
expect(() => parser.parseSync()).toThrow(
"Option '--checkpointSyncUrl' is a single-value flag but was provided multiple times"
);
expect(() => parser.parseSync()).toThrow(
"https://checkpoint-sync.fusaka-devnet-4.ethpandaops.io"
);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Calling parser.parseSync() multiple times is inefficient. It's better to perform a single parse and check the thrown error message. You can combine these assertions into a single toThrow with a more specific error message that includes the duplicated values.

Suggested change
expect(() => parser.parseSync()).toThrow(
"Option '--checkpointSyncUrl' is a single-value flag but was provided multiple times"
);
expect(() => parser.parseSync()).toThrow(
"https://checkpoint-sync.fusaka-devnet-4.ethpandaops.io"
);
expect(() => parser.parseSync()).toThrow(
"Option '--checkpointSyncUrl' is a single-value flag but was provided multiple times. Received values: [https://checkpoint-sync.fusaka-devnet-4.ethpandaops.io, https://checkpoint-sync.fusaka-devnet-4.ethpandaops.io]. Please provide only one value."
);

Copy link
Member

@nflaig nflaig left a comment

Choose a reason for hiding this comment

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

please make sure your code passes yarn build, yarn lint and yarn check-types

@philknows philknows marked this pull request as draft October 27, 2025 16:33
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.

Error Parsing Duplicated Single-Value Flag

2 participants