google-gemini / google-gemini/gemini-cli

A2A server shallow-merges user and workspace settings, causing nested config to be lost

Open
#25,747 8 comments 0 reactions 0 assignees View on GitHub
area/core effort/small kind/bug priority/p2 status/bot-triaged
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

## Summary

The A2A server currently combines user settings and workspace settings with a shallow object spread in [packages/a2a-server/src/config/settings.ts](packages/a2a-server/src/config/settings.ts:128). That means any nested object defined in workspace settings replaces the entire corresponding object from user settings, instead of overriding only the specific keys the workspace intended to change.

This can silently drop valid user configuration.

## Why this is a bug

The A2A server settings structure includes nested sections such as:
- `tools`
- `telemetry`
- `fileFiltering`
- `experimental`

Right now, settings are merged like this in effect:

```ts
return {
...userSettings,
...workspaceSettings,
};
```

That is a shallow merge, as in if both user and workspace settings define the same top-level object, the workspace version replaces the whole object. Any keys present only in the user settings disappear.

That results in unexpected behavior for end users because repo-level settings should usually override specific fields, not erase unrelated defaults they set globally.

## Concrete example

User settings:

```json
{
"fileFiltering": {
"respectGitIgnore": true,
"enableRecursiveFileSearch": true
}
}
```

Workspace settings:

```json
{
"fileFiltering": {
"respectGitIgnore": false
}
}
```

Expected merged result:

```json
{
"fileFiltering": {
"respectGitIgnore": false,
"enableRecursiveFileSearch": true
}
}
```

Current actual result:

```json
{
"fileFiltering": {
"respectGitIgnore": false
}
}
```

The user's `enableRecursiveFileSearch` setting is silently lost.

## Evidence in the codebase

The shallow merge happens in:
- [packages/a2a-server/src/config/settings.ts](packages/a2a-server/src/config/settings.ts:128)

There is already a TODO indicating the settings handling is incomplete:
- [packages/a2a-server/src/config/settings.ts](packages/a2a-server/src/config/settings.ts:23)

The current test suite also encodes the shallow behavior:
- [packages/a2a-server/src/config/settings.test.ts](packages/a2a-server/src/config/settings.test.ts:127)

That test currently expects nested values like `enableRecursiveFileSearch` to become `undefined`, which reflects the bug rather than the desired behavior.

For comparison, the main CLI already uses deep merge logic for settings:
- [packages/cli/src/config/settings.ts](packages/cli/src/config/settings.ts:257)

## Proposed changes
1. Change the A2A server settings merge logic in [packages/a2a-server/src/config/settings.ts](packages/a2a-server/src/config/settings.ts:128) so nested settings objects are merged instead of replaced wholesale.
2. Preserve current precedence rules: workspace settings should still override user settings, but only for explicitly provided nested keys.
3. Add or update tests in [packages/a2a-server/src/config/settings.test.ts](packages/a2a-server/src/config/settings.test.ts:127) to verify that:
- `fileFiltering` merges correctly
- partial workspace overrides do not erase unrelated user keys
- similar nested sections such as `tools`, `telemetry`, and `experimental` behave correctly if applicable
4. Update the existing shallow-merge test so it reflects the intended merged behavior rather than the current replacement behavior.
5. If there is existing shared merge logic in the main CLI that can be reused safely, prefer reusing that approach rather than inventing a second merge strategy.

## Expected outcome
After the fix, users should be able to define global defaults in user settings and have workspace settings override only the specific nested values they need, without silently losing unrelated configuration.

## Possible acceptance criteria
[] User and workspace settings merge correctly for nested objects
[] Partial workspace overrides preserve unspecified user values
[] Test coverage exists for at least one nested settings object, ideally `fileFiltering`
[] No regressions in existing A2A settings loading behavior outside the merge semantics

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.