Skip to content

feat(cli): support boolean and number casting for env vars in settings.json#26118

Merged
cocosheng-g merged 11 commits intomainfrom
boolean-setting
Apr 28, 2026
Merged

feat(cli): support boolean and number casting for env vars in settings.json#26118
cocosheng-g merged 11 commits intomainfrom
boolean-setting

Conversation

@cocosheng-g
Copy link
Copy Markdown
Contributor

Summary

Support boolean and number types when configuring settings.json via environment variables.

Details

Currently, environment variables in settings.json are expanded as strings. This causes validation errors for settings that expect boolean or number types (e.g., ui.autoThemeSwitching or model.maxSessionTurns).

This PR:

  • Uses z.preprocess in settings-validation.ts to automatically cast strings like "true", "false", or numeric strings to their respective types during validation.
  • Delays configuration validation in settings.ts until after environment variable expansion has occurred.
  • Ensures that the successfully cast and validated data is preserved and used by the application.

Related Issues

Fixes #25573

How to Validate

Manual Verification:

  1. Update ~/.gemini/settings.json to use placeholders:
    {
      "ui": { "autoThemeSwitching": "${GEMINI_AUTO_THEME:-false}" },
      "model": { "maxSessionTurns": "${GEMINI_MAX_TURNS:-7}" }
    }
  2. Run gemini and check /settings:
    • No env vars: Should show false and 7.
    • GEMINI_AUTO_THEME=true GEMINI_MAX_TURNS=42 gemini: Should show true and 42.
  3. Verify case-insensitivity: GEMINI_AUTO_THEME=TRUE gemini should result in true.
  4. Verify invalid types: GEMINI_MAX_TURNS=not-a-number gemini should show a validation warning and fall back to default.

Automated Tests:

Run the configuration tests:

npm test -w @google/gemini-cli -- src/config/settings.test.ts src/config/settings-validation.test.ts

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run

@cocosheng-g cocosheng-g requested a review from a team as a code owner April 28, 2026 14:59
@gemini-cli gemini-cli Bot added the area/core Issues related to User Interface, OS Support, Core Functionality label Apr 28, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 significantly improves the CLI's configuration system by introducing robust type casting for environment variables used within settings.json. By allowing string-based environment variables to be correctly interpreted as boolean or number types, it resolves previous validation issues and enhances the overall flexibility and reliability of how settings are managed and applied.

Highlights

  • Environment Variable Type Casting: Enabled automatic type casting for boolean and number environment variables when used in settings.json, allowing string representations like "true" or "42" to be correctly interpreted as their respective types.
  • Delayed Settings Validation: Refactored the settings loading process to delay configuration validation until after environment variables have been expanded, preventing validation errors caused by string-typed environment variable values.
  • Improved Configuration Robustness: Ensured that successfully cast and validated data from environment variables is preserved and correctly utilized by the application, enhancing the flexibility and reliability of CLI configuration.
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.

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.

@cocosheng-g cocosheng-g self-assigned this Apr 28, 2026
@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
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 moves settings validation to occur after environment variable resolution and introduces preprocessing for numeric and boolean values to handle string-based environment variables. A high-severity security concern was identified in the validation logic, which currently falls back to the original settings on failure instead of failing closed, potentially allowing invalid or insecure configurations to be used.

Comment thread packages/cli/src/config/settings.ts Outdated
Copy link
Copy Markdown
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 type casting for configuration settings during validation, enabling string representations of booleans and numbers—commonly sourced from environment variables—to be correctly parsed. The validation logic has been relocated to execute after environment variable expansion to ensure accurate type checking. Feedback was provided regarding the validateAndRecordErrors function, suggesting a more functional approach to avoid mutating the settingsErrors array from the outer scope.

Comment thread packages/cli/src/config/settings.ts Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

Size Change: +1.04 kB (0%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-2LUSSFFI.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-QFLLGUPL.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-VUV5JXQ2.js 0 B -673 kB (removed) 🏆
./bundle/chunk-WHRIYUZ4.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-YIMBEFFC.js 0 B -2.73 MB (removed) 🏆
./bundle/chunk-ZJWCL27O.js 0 B -3.8 kB (removed) 🏆
./bundle/core-C2IIG6KX.js 0 B -48.1 kB (removed) 🏆
./bundle/devtoolsService-CM2PR4UG.js 0 B -27.8 kB (removed) 🏆
./bundle/gemini-N3SGFNGF.js 0 B -574 kB (removed) 🏆
./bundle/interactiveCli-AW7X7I6V.js 0 B -1.31 MB (removed) 🏆
./bundle/liteRtServerManager-6WNCFMIF.js 0 B -2.08 kB (removed) 🏆
./bundle/oauth2-provider-H2GVOQXF.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-3EIXOO77.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-3ZPALGFT.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-D3IQ6AJK.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-MU5X5EJK.js 674 kB +674 kB (new file) 🆕
./bundle/chunk-PCSZJ45Z.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-RJWXONOQ.js 2.73 MB +2.73 MB (new file) 🆕
./bundle/core-EOZB656U.js 48.1 kB +48.1 kB (new file) 🆕
./bundle/devtoolsService-X4G2WXOX.js 27.8 kB +27.8 kB (new file) 🆕
./bundle/gemini-UEIGPTAN.js 574 kB +574 kB (new file) 🆕
./bundle/interactiveCli-6ME5H4LT.js 1.31 MB +1.31 MB (new file) 🆕
./bundle/liteRtServerManager-JBVEUBWP.js 2.08 kB +2.08 kB (new file) 🆕
./bundle/oauth2-provider-7KR46DD4.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-MTD736U4.js 1.97 MB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-JBJVGYBA.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 4.97 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-NSOLCG4U.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-YPV7G5IA.js 0 B -622 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-SMUHWNRC.js 932 B +932 B (new file) 🆕
./bundle/start-FNGKQSX2.js 622 B +622 B (new file) 🆕

compressed-size-action

@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
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 type casting for numeric and boolean settings during validation, allowing environment variables to be correctly parsed into their respective types. It also shifts the validation process to occur after environment variable expansion to ensure final values are checked. A critical security concern was identified in the new validation logic: the implementation currently 'fails open' by returning an empty object when validation fails, which could allow security configurations in high-precedence files to be bypassed by falling back to less restrictive defaults.

Comment thread packages/cli/src/config/settings.ts Outdated
@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
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 automatic type casting for configuration settings and ensures environment variables are resolved before validation. Specifically, the buildPrimitiveSchema function now uses Zod's preprocess to cast string representations of booleans and numbers to their respective types. The settings loading logic was updated to resolve environment variables prior to validation, allowing for more robust configuration handling. Comprehensive tests were added to verify these casting and resolution behaviors. I have no feedback to provide.

@cocosheng-g cocosheng-g requested a review from devr0306 April 28, 2026 17:02
Comment thread packages/cli/src/config/settings-validation.test.ts Outdated
Comment thread packages/cli/src/config/settings.ts
@cocosheng-g cocosheng-g requested review from a team and removed request for devr0306 April 28, 2026 17:06
@devr0306
Copy link
Copy Markdown
Contributor

devr0306 commented Apr 28, 2026

From /review-frontend

Summary

The PR correctly identifies and addresses the need for type casting when environment variables are used in settings.json. However, there are a few critical and structural issues that need to be addressed before merging.

Critical Issues

1. Environment Variable Placeholder Loss on Save

In packages/cli/src/config/settings.ts, the load function now returns expanded settings. These expanded settings are then used to populate originalSettings:

const userOriginalSettings = structuredClone(userResult.settings);

Since saveSettings uses originalSettings to write back to the file, any save operation (e.g., changing a setting in the UI) will replace the environment variable placeholders (like "$MY_VAR") with their current values (like "true"). This breaks the "source of truth" for users who want to keep placeholders in their config.

Recommendation: The load function should return both the raw settings (with placeholders) and the expanded settings. originalSettings should be derived from the raw settings.

2. Inconsistent Casting in Shared Definitions (refs)

The casting logic was added to buildPrimitiveSchema, but buildZodSchemaFromJsonSchema (which builds REF_SCHEMAS) still uses standard z.boolean() and z.number().
Impact: Settings using shared definitions (like MCPServerConfig for mcpServers) will still fail validation if environment variables are used. For example, mcpServers.my-server.trust: "$TRUST" will not be cast.

Recommendation: Refactor buildZodSchemaFromJsonSchema to use buildPrimitiveSchema for consistent casting across all definitions.

Suggestions for Improvement

3. Test Assertions

In packages/cli/src/config/settings-validation.test.ts, the test it('should reject invalid castable strings', ...) should verify the specific error message to ensure it's failing for the right reason (type mismatch) rather than just "any error".

4. Type Safety in Tests

Avoid using // eslint-disable-next-line @typescript-eslint/no-explicit-any in tests. Prefer narrowing or using unknown with a cast to a partial of the expected type if needed for assertion.

@cocosheng-g
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
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 implements automatic type casting for configuration settings, allowing environment variables to be correctly validated as numbers or booleans. It introduces Zod preprocessing to handle string-to-primitive conversions and updates the settings loading process to resolve environment variables before validation while preserving original placeholders for persistence. I have no feedback to provide.

@cocosheng-g cocosheng-g enabled auto-merge April 28, 2026 17:25
@cocosheng-g cocosheng-g added this pull request to the merge queue Apr 28, 2026
Merged via the queue into main with commit c841070 Apr 28, 2026
27 checks passed
@cocosheng-g cocosheng-g deleted the boolean-setting branch April 28, 2026 17:45
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support boolean types when configuring settings.json via environment variables

3 participants