google-gemini / google-gemini/gemini-cli

bug(core): unbounded _execute recursion on sandbox_expansion_required can loop forever (scheduler.ts)

Open
#29,309 4 comments 0 reactions 0 assignees View on GitHub
area/core effort/medium kind/bug priority/p2 status/manual-triage status/need-information
Dominant language
TypeScript
Stars
107k
Forks
14.6k
Avg merge
2d 3h
Merged PRs (30d)
45

Description

## What happened?

`packages/core/src/scheduler/scheduler.ts:927-934` recursively calls `this._execute()` when a tool returns `sandbox_expansion_required`, with no counter or depth limit:

```ts
// Call _execute synchronously and properly return its promise to loop internally!
return await this._execute(
{ ...activeCall, status: CoreToolCallStatus.Scheduled } as ScheduledToolCall,
signal,
);
```

A malicious or buggy tool returning `sandbox_expansion_required` on every call recurses forever (stack growth / infinite loop). The surrounding `catch {}` falls through silently.

## What did you expect to happen?

Bounded retry: iterative loop with `maxSandboxExpansions` (e.g. 2–3), then fail the call with an error and surface retry count in telemetry. Abort signal should also break the loop.

## Client information

- Repo `google-gemini/gemini-cli` @ `main` `9c1b0a610`
- Area `packages/core/src/scheduler/scheduler.ts:927-934`
- Platform: source checkout

## Login information

N/A — scheduler logic; repro with a stub tool always returning `sandbox_expansion_required`.

## Anything else we need to know?

Fix direction: replace recursion with loop + counter, emit `sandbox_expansion_retry` telemetry, add regression test asserting 3rd consecutive request fails instead of recursing. Related hardening track #29214/#29216.

Contributor guide

Open the contributing guide

Research direction

Start in packages/core/src/scheduler/scheduler.ts:927-934 and trace the _execute path for sandbox_expansion_required. Reproduce the behavior with a stub tool that always returns that status, then add a regression test showing the third consecutive request fails, the retry count is reported in telemetry, and the abort signal breaks the loop.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.