Better FS Tools
Comparisons

Gemini CLI

Read, edit, shell, and search tools in Gemini CLI at 0.62.0-nightly, with every model-facing description in full for both declaration sets

Gemini CLI is Google's open-source terminal coding agent. Its model-facing file family is seven dedicated tools, read_file, read_many_files, list_directory, glob, grep_search, replace, and write_file, plus run_shell_command and two background-process readers. The tool declarations come in two sets chosen by model family: a default-legacy set for every model outside the Gemini 3 family, and a Gemini 3 set whose read_file, write_file, grep_search, and replace strings differ. Paths are canonicalised and checked against the workspace roots before any I/O, and a central policy engine decides which calls need confirmation.

Source

ItemValue
Repositorygoogle-gemini/gemini-cli
Commit6a466a7e2fe2b1255752c1e74f69b31f0216084d, committed 2026-09-15
Last updated2026-09-16

Tool inventory

ToolPurposeDefaultNotes
read_fileRead a text file by line range, or a media file as an inline partYesTwo description strings, one per declaration set
read_many_filesRead glob-selected files and concatenate themNoNot registered by createToolRegistry() at this pin; constructed by the @ path processor and the ACP session
list_directoryList the direct children of one directoryYes
globFind file paths by glob patternYesnpm glob package
grep_searchSearch file contents by regexYesRipGrepTool when useRipgrep is on and a binary is found, otherwise GrepTool under the same name. Two description strings
replaceReplace one or all occurrences of a string in one fileYesSource class EditTool. Two description strings
write_fileCreate or overwrite a whole fileYesTwo description strings
run_shell_commandRun one command in bash -c or PowerShellYesDescription rendered from platform and settings
list_background_processesList managed background processes for the sessionYesRegistered after run_shell_command
read_background_outputRead the tail of a managed background logYesRegistered after run_shell_command

The tools.core allowlist can remove any built-in. Every declarative schema also receives an extra wait_for_previous boolean that the scheduler uses as a barrier. getToolFamily(modelId) in modelFamilyService.ts returns gemini-3 when isGemini3Model() matches the active model and default-legacy otherwise; the two sets share every parameter name and type, and differ in description strings and some parameter-level descriptions. MCP resource tools and discovered tools are outside this page.

Read

Signature

read_file({ file_path: string, start_line?: integer, end_line?: integer })
read_many_files({ include: string[], exclude?: string[], recursive?: boolean, useDefaultExcludes?: boolean, file_filtering_options?: { respect_git_ignore?: boolean, respect_gemini_ignore?: boolean } })

file_path is relative or absolute; a relative path resolves against the target directory. start_line and end_line are one-based and inclusive, typed as integers with minimum 1. With neither, the first 2000 lines are returned. With start_line alone, 2000 lines from that line. end_line past the end is clamped. start_line greater than end_line fails validation with start_line cannot be greater than end_line. The parameter names and types are identical in both declaration sets.

Description

read_file, default-legacy: 444 characters, 444 bytes, 1 line, approximately 111 tokens. read_file, Gemini 3 family: 552 characters, 552 bytes, 1 line, approximately 131 tokens. read_many_files: 1936 characters, 1936 bytes, 10 lines, approximately 401 tokens. Identical in both sets.

read_file, default-legacy (444 characters)

Reads and returns the content of a specified file. If the file is large, the content will be truncated. The tool's response will clearly indicate if truncation has occurred and will provide details on how to read more of the file using the 'start_line' and 'end_line' parameters. Handles text, images (PNG, JPG, GIF, WEBP, SVG, BMP), audio files (MP3, WAV, AIFF, AAC, OGG, FLAC), and PDF files. For text files, it can read specific line ranges.

read_file, Gemini 3 family (552 characters)

The Gemini 3 set is selected when isGemini3Model() matches the active model ID.

Reads and returns the content of a specified file. To maintain context efficiency, you MUST use 'start_line' and 'end_line' for targeted, surgical reads of specific sections. For your safety, the tool will automatically truncate output exceeding 2000 lines, 2000 characters per line, or 20MB in size; however, triggering these limits is considered token-inefficient. Always retrieve only the minimum content necessary for your next step. Handles text, images (PNG, JPG, GIF, WEBP, SVG, BMP), audio files (MP3, WAV, AIFF, AAC, OGG, FLAC), and PDF files.

read_many_files (1936 characters)

Reads content from multiple files specified by glob patterns within a configured target directory. For text files, it concatenates their content into a single string. It is primarily designed for text-based files. However, it can also process image (e.g., .png, .jpg), audio (e.g., .mp3, .wav), and PDF (.pdf) files if their file names or extensions are explicitly included in the 'include' argument. For these explicitly requested non-text files, their data is read and included in a format suitable for model consumption (e.g., base64 encoded).

This tool is useful when you need to understand or analyze a collection of files, such as:
- Getting an overview of a codebase or parts of it (e.g., all TypeScript files in the 'src' directory).
- Finding where specific functionality is implemented if the user asks broad questions about code.
- Reviewing documentation files (e.g., all Markdown files in the 'docs' directory).
- Gathering context from multiple configuration files.
- When the user asks to "read all files in X directory" or "show me the content of all Y files".

Use this tool when the user's query implies needing the content of several files simultaneously for context, analysis, or summarization. For text files, it uses default UTF-8 encoding and a '--- {filePath} ---' separator between file contents. The tool inserts a '--- End of content ---' after the last file. Ensure glob patterns are relative to the target directory. Glob patterns like 'src/**/*.js' are supported. Avoid using for single files if a more specific single-file reading tool is available, unless the user specifically requests to process a list containing just one file via this tool. Other binary files (not explicitly requested as image/audio/PDF) are generally skipped. Default excludes apply to common non-text files (except for explicitly requested images/audio/PDFs) and large dependency directories unless 'useDefaultExcludes' is false.

Path handling

resolveDefensiveToolPath removes NUL bytes and strips a leading @ when the literal path does not exist and no @-prefixed entry exists for the first segment. resolveToRealPath accepts a file:// URL, percent-decodes the string, resolves it against the target directory, and takes the real path with realpathSync; for a missing leaf it resolves the existing symlink ancestors. No tilde expansion. Symlinks are followed before the workspace check, so a link inside the workspace whose target is outside fails the check. A real-path failure returns Failed to resolve path: <message>.

Near-miss recovery: None. A missing file returns:

File not found: <path>

The message travels in the function response error field. The tool's llmContent for that case, Could not read file because no file was found at the specified path., is dropped by the executor when an error is set; see Errors.

Permissions

CheckBehaviour
Policyread_file, glob, grep_search, and list_directory are allowed by policies/read-only.toml at priority 50. No confirmation under the shipped policy files; user and admin rules can override
Workspace rootsThe real path must sit under a workspace directory, an added read-only directory, or the project temp directory. The global personal GEMINI.md is a single-file exception. Otherwise Path not in workspace: Attempted path "<path>" resolves outside the allowed workspace directories: <dirs> or the project temp directory: <tmp>
Blocked segments.git, .env, node_modules, and gha-creds-*.json anywhere in the workspace-relative path, including NTFS 8.3 short-name forms, fail the workspace check with the same Path not in workspace message
Ignore rules.gitignore and .geminiignore apply by default: File path '<path>' is ignored by configured ignore patterns.
Path syntaxNewlines, control characters, NUL, a path over 4096 characters, or a component over 255 characters: Invalid path: <reason>
Auto-memory inboxDenied to the main agent even though it sits under the project temp directory
Device and special filesNone. Only stats.isDirectory() is checked before readFile, so a FIFO or device inherits Node behaviour
Denial textValidation failures are returned as Error: Invalid parameters provided. Reason: <message>

Binary and conversion

AspectBehaviour
Detection.ts, .mts, .cts are forced to text. .svg is its own type. Otherwise a mime lookup: image/* is image, audio/* and video/* are confirmed with isbinaryfile or fall back to text, application/pdf is PDF. Then the supported audio extension map, then the BINARY_EXTENSIONS list, then an isbinaryfile content check
RefusalCannot display content of binary file: <rel> returned as success text with no error field
NotebooksNone. .ipynb reads as JSON text
Office and PDF textNone
SVGRead as text up to 1 MiB; Cannot display content of SVG file larger than 1MB: <rel> as success text above that
ImagesAny image/* MIME type; the whole file is base64-encoded into an inlineData part
PDFinlineData part
Audio and videoMP3, WAV, AIFF, AAC, OGG, FLAC by extension or normalised MIME type as inlineData; an audio MIME outside that set errors with Unsupported audio file format for <path>. Supported audio formats are MP3, WAV, AIFF, AAC, OGG, and FLAC.; video by video/* MIME after the binary check
Media size guardThe 20 MiB cap below applies to every type before the read
EncodingBOM-aware: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE detected and stripped; no BOM decodes as UTF-8

Limits

LimitValueMessage
Default window2000 lines
CeilingThe model's end_line, clamped to the file length. No cap on the requested range
Long lineCut at 2000 characters... [truncated] appended to the line; the banner below also appears
Whole-file size20 MiB for every type, checked on stat before the readFile size exceeds the 20MB limit: <path> (<size>MB)
Output budgetNone in the tool. Shell output has an outer cap; read output does not unless context management is enabled
Offset past endEmpty content under the banner, not an errorStatus: Showing lines <total+1>-<total> of <total> total lines.
Line splitting\r?\n, so CRLF files count the same lines

Output

import { x } from "./x"
export const y = x

When the read stopped before the end, when start_line was above 1, or when any line was cut, a banner precedes the content:


IMPORTANT: The file content has been truncated.
Status: Showing lines 1-2000 of 5000 total lines.
Action: To read more of the file, you can use the 'start_line' and 'end_line' parameters in a subsequent 'read_file' call. For example, to read the next section of the file, use start_line: 2001.

--- FILE CONTENT (truncated) ---
import { x } from "./x"
AspectBehaviour
Prefix before contentNone on a plain read. The banner block, starting with a blank line, when isTruncated is set
Line prefixNone. Lines are bare
End markerNone
Truncation noticeThe banner above, before the content. A ranged read the model asked for also gets it, so a request for lines 50 to 60 is told the content was truncated
Error transportFunction response { error: "<message>" } with no output field

Both examples are reconstructed from the format code. The success response to the model is { output: "<text>" } inside the function response, or an inlineData part for media.

Notable

  • After the content, JIT context discovered for the file's directory can be appended between --- Newly Discovered Project Context --- and --- End Project Context ---, so the result can carry GEMINI.md text that is not in the requested file.
  • No repeat-read guard, no redaction, no explicit empty-file notice. An empty file returns an empty string.
  • read_file does not read the abort signal; execute ignores its options.
  • The UI summary for a ranged read is Read lines <a>-<b> of <total> from <rel>; a plain full read shows nothing.
  • read_many_files expands include in every workspace directory, filters through the discovery service, validates each path, sorts, and processes files with Promise.allSettled. Text goes out under --- <path> --- separators with --- End of content --- after the last file. Skipped files are reported by path and reason; the reason strings: Not surveyed. There is no shared snapshot across the files.
  • The scheduler runs read_file calls in parallel with other parallelizable calls unless the model sets wait_for_previous.

Edit

Signature

write_file({ file_path: string, content: string })
replace({ file_path: string, old_string: string, new_string: string, instruction: string, allow_multiple?: boolean })

The model name is replace; the source class is EditTool. instruction is required and is only used by the optional LLM correction path. allow_multiple is a boolean. There is no delete tool and no multi-file patch tool. replace and write_file are in EDIT_TOOL_NAMES, which the scheduler treats as ordered barriers. Both declaration sets share the parameter names and types; the Gemini 3 set shortens the parameter-level descriptions.

Description

write_file, default-legacy: 162 characters, 162 bytes, 3 lines, approximately 33 tokens. write_file, Gemini 3 family: 304 characters, 304 bytes, 1 line, approximately 59 tokens. replace, default-legacy: 2063 characters, 2063 bytes, 12 lines, approximately 421 tokens. replace, Gemini 3 family: 571 characters, 571 bytes, 2 lines, approximately 111 tokens.

write_file, default-legacy (162 characters)

Writes content to a specified file in the local filesystem.

      The user has the ability to modify `content`. If modified, this will be stated in the response.

write_file, Gemini 3 family (304 characters)

Selected with the Gemini 3 declaration set.

Writes the complete content to a file, automatically creating missing parent directories. Overwrites existing files. The user has the ability to modify 'content' before it is saved. Best for new or small files; use 'replace' for targeted edits to large files to minimize token usage and simplify reviews.

replace, default-legacy (2063 characters)

Replaces text within a file. By default, the tool expects to find and replace exactly ONE occurrence of `old_string`. If you want to replace multiple occurrences of the exact same string, set `allow_multiple` to true. This tool requires providing significant context around the change to ensure precise targeting. Always use the read_file tool to examine the file's current content before attempting a text replacement.
      
      The user has the ability to modify the `new_string` content. If modified, this will be stated in the response.
      
      Expectation for required parameters:
      1. `old_string` MUST be the exact literal text to replace (including all whitespace, indentation, newlines, and surrounding code etc.).
      2. `new_string` MUST be the exact literal text to replace `old_string` with (also including all whitespace, indentation, newlines, and surrounding code etc.). Ensure the resulting code is correct and idiomatic and that `old_string` and `new_string` are different.
      3. `instruction` is the detailed instruction of what needs to be changed. It is important to Make it specific and detailed so developers or large language models can understand what needs to be changed and perform the changes on their own if necessary. 
      4. NEVER escape `old_string` or `new_string`, that would break the exact literal text requirement.
      **Important:** If ANY of the above are not satisfied, the tool will fail. CRITICAL for `old_string`: Must uniquely identify the instance(s) to change. Include at least 3 lines of context BEFORE and AFTER the target text, matching whitespace and indentation precisely. If this string matches multiple locations and `allow_multiple` is not true, the tool will fail.
      5. Prefer to break down complex and long changes into multiple smaller atomic calls to this tool. Always check the content of the file after changes or not finding a string to match.
      **Multiple replacements:** Set `allow_multiple` to true if you want to replace ALL occurrences that match `old_string` exactly.

replace, Gemini 3 family (571 characters)

Selected with the Gemini 3 declaration set.

Replaces text within a file. By default, the tool expects to find and replace exactly ONE occurrence of `old_string`. If you want to replace multiple occurrences of the exact same string, set `allow_multiple` to true. This tool is preferred for surgical edits to existing files as it minimizes token usage, simplifies code reviews, and avoids accidental deletions. This tool requires providing significant context around the change to ensure precise targeting.
The user has the ability to modify the `new_string` content. If modified, this will be stated in the response.

Whole-file write

write_file validates the path, rejects a directory target with Path is a directory, not a file: <path>, and rejects content that holds an omission placeholder such as rest of methods .... The confirmation step reads the current file, builds a unified diff, and lets the user change the content. Execution reads the file again, creates missing parent directories, and calls StandardFileSystemService.writeTextFile, which is fs.writeFile(path, content, 'utf-8'). The write is direct: no temporary file, no rename, no mode preservation, no post-write verification. Line endings: when the existing file used CRLF, every line ending in the new content is converted to CRLF; for a new file the OS default applies. BOM: the service reads and writes UTF-8 as-is, so an existing BOM survives only if the model's content contains it. In plan mode the path is redirected into the plans directory.

Content correction: with disableLLMCorrection at its default true, no model call is made. An unescape pass still runs for models outside the Gemini 2 and Gemini 3 families and custom models; Gemini 2 and 3 models get the content as supplied. JSON and notebook files skip the pass.

Matching

replace reads the file once inside the call, normalises CRLF to LF, and runs a cascade: exact, then line-trimmed flexible, then a token regex that allows whitespace between tokens, then a bounded Levenshtein fuzzy match for old_string of at least ten characters with a 10 percent weighted difference limit and a work cap of lines * length^2 <= 4e8. The first strategy that finds a candidate wins. Without allow_multiple the count must be exactly one. A fuzzy match is reported to the model as Applied fuzzy match at line <n>. or lines <a>-<b>; flexible and regex matches are not reported. An empty old_string creates the file when it does not exist and errors when it does. Equal old_string and new_string is an error. Validation completes before the write, so a miss leaves the file unchanged.

When every strategy misses and disableLLMCorrection is false, FixLLMEditWithInstruction asks a secondary model for a corrected pair. The path hashes the first read, re-reads the file, and uses the newer content when the hash changed. JSON, JSONC, JSON5, and notebook files skip correction. The setting defaults to true, so this path is off unless the user enables it. The correction prompt itself: Not surveyed.

Multi-file patch

None. replace covers one file per call. There is no patch grammar and no multi-file tool.

Verification and mutation state

ConcernBehaviour
Read-before-writeDescribed to the model in the default-legacy replace string; not enforced. write_file accepts any destination
Stale-file checkNone on the normal path. The LLM-correction path compares a SHA-256 of the in-call read against a re-read, only when correction is enabled and the first match failed
LockNone. The scheduler forces replace and write_file into ordered barriers within one batch; there is no path lock shared with run_shell_command, background processes, or other CLI instances
Cross-process coordinationNone
Post-write checksNone. No syntax or LSP check
Change trackingBuild-file writes are recorded for a later reminder; the UI receives a diff and diff statistics

Output

ToolModel text
write_fileSuccessfully created and wrote to new file: <path>. or Successfully overwrote file: <path>., then Here is the updated code: and a five-line diff context snippet. User modified the `content` to be: <content> is inserted when the user edited the content
replaceCreated new file: <path> with provided content. or Successfully modified file: <path> (<n> replacements)., then Here is the updated code: and the snippet, then the fuzzy-match note when it applies, then The confirmation step modified the `new_string` content to be: <text>. when the user edited it

JIT project context can follow either message. The full unified diff, diff statistics, and the isNewFile flag go to returnDisplay for the UI, not to the model.

Notable

  • The confirmation for both tools shows a diff and can open the IDE diff view; the user can alter the proposed content before it is written, and the model is told.
  • No notebook editor, no undo tool, no checkpoint tool in this family.
  • The replace description promises exact matching; the runtime accepts the flexible, regex, and fuzzy cascade above.
  • write_file and replace in autoEdit mode are allowed after an in-process allowed-path safety checker; in plan mode the read-only policy denies them.
  • The default-legacy write_file description says nothing about parent creation or overwrite; the runtime does both.

Shell

Signature

run_shell_command({ command: string, description?: string, dir_path?: string, is_background?: boolean, delay_ms?: integer, additional_permissions?: object })
list_background_processes({})
read_background_output({ pid: integer, lines?: integer, delay_ms?: integer })

additional_permissions is added to the schema only when tool sandboxing is enabled; it carries network and fileSystem.read and fileSystem.write path lists. dir_path resolves against the target directory and must pass the workspace check. delay_ms sets how long a background command runs before the call returns; the default is 200 ms. lines on read_background_output defaults to 100. There is no timeout parameter.

Description

run_shell_command: 1222 characters, 1222 bytes, 14 lines, approximately 269 tokens. Rendered for Linux with enableInteractiveShell=true and enableShellOutputEfficiency=true. The same helper serves both declaration sets, so there is one string. Windows renders a PowerShell variant; with the interactive shell off the background sentence tells the model to use & instead. list_background_processes: 94 characters, 94 bytes, 1 line, approximately 15 tokens. Identical in both sets. read_background_output: 82 characters, 82 bytes, 1 line, approximately 15 tokens. Identical in both sets.

run_shell_command (1222 characters)

This tool executes a given shell command as `bash -c <command>`. To run a command in the background, set the `is_background` parameter to true. Do NOT use `&` to background commands. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as `kill -- -PGID` or signaled as `kill -s SIGNAL -- -PGID`.

      Efficiency Guidelines:
      - Quiet Flags: Always prefer silent or quiet flags (e.g., `npm install --silent`, `git --no-pager`) to reduce output volume while still capturing necessary information.
      - Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use `git --no-pager`, `systemctl --no-pager`, or set `PAGER=cat`).

      The following information is returned:

      Output: Combined stdout/stderr. Can be `(empty)` or partial on error and for any unwaited background processes.
      Exit Code: Only included if non-zero (command failed).
      Error: Only included if a process-level error occurred (e.g., spawn failure).
      Signal: Only included if process was terminated by a signal.
      Background PIDs: Only included if background processes were started.
      Process Group PGID: Only included if available.

list_background_processes (94 characters)

Lists all active and recently completed background shell processes orchestrating by the agent.

read_background_output (82 characters)

Reads the output log of a background shell process. Support reading tail snapshot.

Working directory and environment

The working directory is the target directory unless dir_path is given; the resolved directory must pass validatePathAccess. Unix commands run as bash -c <command>; Windows uses the configured PowerShell or command shell path. ShellExecutionService sanitises the environment, sets GEMINI_CLI=1, disables Git credential and interactive prompts, applies pager defaults, and asks the configured SandboxManager to prepare the command. On non-Windows hosts the command is wrapped with a POSIX EXIT trap that records child background PIDs to a temp file. Login shell: None.

Process lifecycle

AspectBehaviour
ModelOne process per call. node-pty when the interactive shell is enabled and a PTY implementation loads, otherwise child_process. The child leads its own process group on supported Unix systems, except under Bun
Backgroundis_background starts the process, waits delay_ms, and returns Command is running in background. PID: <pid>. Initial output: with the output so far when the process is still running. The execution stays managed in ShellExecutionService; completion can inject output into the conversation or stay silent
stdinThe UI can write input to an active PTY; the model cannot
CancellationAbort or inactivity timeout kills the process group with escalation and waits for the close event
GrandchildrenPIDs captured by the EXIT trap are reported as Background PIDs:; they are not managed unless is_background was used
Late exitsThe lifecycle service keeps exit information for five minutes; the session history holds at most 100 records

The inactivity timeout comes from tools.shell.inactivityTimeout, 300 seconds by default; any output, binary-progress, or exit event resets it. A timeout returns Command was automatically cancelled because it exceeded the timeout of <n> minutes without output. followed by Below is the output before it was cancelled: and the output, or There was no output before it was cancelled.

Output limits

AspectBehaviour
Collectionstdout and stderr are decoded separately and appended to one ordered string. The child-process buffer keeps at most 16 MiB as a rolling tail and appends [GEMINI_CLI_WARNING: Output truncated. The buffer is limited to 16MB.] when it overflowed. PTY mode uses xterm scrollback up to 300 000 lines
Live buffer100 000 characters for UI updates, refreshed at most once per second
Binary outputA 4 KiB sniff; a binary stream stops text rendering and shows [Binary output detected. Halting stream...], then byte-count progress
Model-visible budgetThe scheduler saves run_shell_command text above truncateToolOutputThreshold, 40 000 characters by default, to tool-outputs/ under the project temp directory and returns Output too large. Showing first 8,000 and last 32,000 characters. For full output see: <file> with the head and tail around ... [<n> characters omitted] .... With context management on, ToolOutputDistillationService can summarise instead
Spill file<projectTempDir>/tool-outputs/session-<sessionId>/<tool>_<callId>.txt. No cleanup deadline in the source
Empty output(empty)
WrapperThe whole shell result is wrapped in an untrusted_context tag pair before it reaches the model

Sandbox

Optional. A full-process sandbox is selected by --sandbox, GEMINI_SANDBOX, or settings, with Docker, Podman, macOS Seatbelt, gVisor, LXC, and a Windows native sandbox as providers; container and LXC modes mount the workspace at its host path. Tool-level sandboxing adds a SandboxManager preparation step to shell execution only: Bubblewrap on Linux and Seatbelt on macOS can deny writes outside the workspace, protect .git, hide secret files such as .env, and grant paths from additional_permissions. A denial can return Sandbox expansion required with a structured request so the model can retry with narrower added paths or network access. Without a selected sandbox, NoopSandboxManager runs and only sanitises the environment; LocalSandboxManager throws Tool sandboxing is not yet implemented.. Direct read_file, write_file, and replace calls never pass through the sandbox manager.

Approval

run_shell_command is ask_user at priority 10 in policies/write.toml. Confirmation shows the parsed root commands, redirections, untrusted flags, and any sandbox expansion, and can produce an allow-once, allow-session, or persistent rule narrowed to a command prefix. Before execution detectCommandSubstitution blocks $(), backticks, <(), and >() in command arguments, and PowerShell @() and $(), with Command injection detected: command substitution syntax ($(), backticks, <() or >()) found in command arguments. ... as success text. yolo allows most tools; plan denies through the read-only policy; an untrusted folder disables yolo and autoEdit. In a non-interactive session the policy engine's default decision is deny. No shipped policy rule names the two background tools, so they take the engine default, ask_user in an interactive session. The confirmation text shown to the user: Not surveyed.

Notable

  • A non-zero exit is a successful tool result. The model text is Output: <text> then Exit Code: <n>, with Signal: <sig>, Background PIDs: <pids>, and Process Group PGID: <pgid> lines when present. Only a spawn failure sets the error field.
  • User cancellation returns Command was cancelled by user before it could complete. plus the output-before-cancel clause, or Command was cancelled by user before it could start. when the signal was already set.
  • read_background_output checks that the PID belongs to the session, opens the predicted log with O_NOFOLLOW, reads at most 64 KiB from the end, and returns Showing last <n> of <total> lines: with the tail. A missing record returns Access denied. Background process ID <pid> not found in this session's history.; a symlink at the log path returns Symbolic link detected at predicted log path. Access is denied for security reasons.
  • list_background_processes returns No background processes found. or one - [PID <pid>] <STATUS>: `<command>` line per record.
  • The default-legacy and Gemini 3 sets call the same shell description helper, so shell text does not change with the model family.

Search and listing

Tools

ToolArgumentsDefault capsIgnore rules
globpattern, dir_path?, case_sensitive?, respect_git_ignore?, respect_gemini_ignore?None in the leaf. Files modified in the last 24 hours first, newest first, then the rest alphabeticallydot: true, follow: false, nodir: true; configured exclusions plus .gitignore and .geminiignore through the discovery service
grep_search (ripgrep)pattern, dir_path?, include_pattern?, exclude_pattern?, names_only?, case_sensitive?, fixed_strings?, context?, before_context?, after_context?, no_ignore?, max_matches_per_file?, total_max_matches?100 total matches; 2000 characters per line with ... [truncated]; 30 second timeout floor, raised by searchTimeoutrg --json; .gitignore native; .geminiignore through --ignore-file; common directory excludes, *.log, *.tmp; no_ignore disables all of them
list_directorydir_path, ignore?, file_filtering_options?None. No offset, limit, or page.gitignore and .geminiignore by default; per-call ignore globs on the basename
Stat, find, mkdirNone

glob searches every workspace root when dir_path is omitted, escapes a pattern that names an existing path, resolves results to real paths, and returns Found <n> file(s) matching "<pattern>" within <dir>, sorted by modification time (newest first): with absolute paths one per line, or No files found matching pattern "<pattern>" within <dir>. An ignored count is appended in parentheses. grep_search returns Found <n> match(es) for pattern "<pattern>" in path "<dir>": then blocks of File: <path> and L<line>: <text> rows between --- lines; context lines use L<line>- <text>. With names_only it lists paths. When one to three matches are found and no context was requested, the ripgrep path re-runs with 50 context lines for one match or 15 for two or three. Zero matches return No matches found for pattern "<pattern>" .... The GrepTool fallback tries git grep, then system grep, then a JavaScript scan, and parses path:line:content text; its output shape: Not surveyed. list_directory returns Directory listing for <dir>: with [DIR] <name> rows first, then <name> (<size> bytes) rows, alphabetical within each group, plus (<n> ignored) when entries were filtered. An empty directory returns Directory <dir> is empty. Entries that fail stat are omitted without a notice.

Description

list_directory: 150 characters, 150 bytes, 1 line, approximately 24 tokens. Identical in both sets. glob: 261 characters, 261 bytes, 1 line, approximately 55 tokens. Identical in both sets. grep_search, default-legacy: 63 characters, 63 bytes, 1 line, approximately 11 tokens. grep_search, Gemini 3 family: 301 characters, 301 bytes, 1 line, approximately 61 tokens.

list_directory (150 characters)

Lists the names of files and subdirectories directly within a specified directory path. Can optionally ignore entries matching provided glob patterns.

glob (261 characters)

Efficiently finds files matching specific glob patterns (e.g., `src/**/*.ts`, `**/*.md`), returning absolute paths sorted by modification time (newest first). Ideal for quickly locating files based on their name or path structure, especially in large codebases.

grep_search, default-legacy (63 characters)

Searches for a regular expression pattern within file contents.

grep_search, Gemini 3 family (301 characters)

Selected with the Gemini 3 declaration set.

Searches for a regular expression pattern within file contents. This tool is FAST and optimized, powered by ripgrep. PREFERRED over standard `run_shell_command("grep ...")` due to better performance and automatic output limiting (defaults to 100 matches, but can be increased via `total_max_matches`).

Errors

ConditionMessage shapeTransport
Missing file on readFile not found: <path>Function response error field; llmContent is dropped
Directory on readPath is a directory, not a file: <path>error field
Path outside workspace or blocked segmentPath not in workspace: Attempted path "<path>" resolves outside the allowed workspace directories: <dirs> or the project temp directory: <tmp>error field, or Error: Invalid parameters provided. Reason: <message> when caught at validation
Ignored path on readFile path '<path>' is ignored by configured ignore patterns.Validation error
OS permission denied on readError reading file <path>: EACCES: permission denied, open '<path>'error field
Binary fileCannot display content of binary file: <rel>Success text, no error field
Too largeFile size exceeds the 20MB limit: <path> (<size>MB)error field
Offset past endNot an error; banner with empty contentSuccess text
Invalid rangestart_line cannot be greater than end_lineValidation error
Edit target missingFile not found: <path>error field
Edit match failedCould not find an exact match for 'old_string' in '<path>'. If previous edits modified the file or you are modifying lines outside your recent read window, please use ReadFile to inspect the target lines before retrying with an exact 'old_string'.error field
Edit not uniqueFailed to edit, Expected 1 occurrence but found <n> for old_string in file: <path>. If you intended to replace multiple occurrences, set 'allow_multiple' to true.error field
Edit no changeNo changes to apply. The old_string and new_string are identical in file: <path>error field
Edit create on existing fileFile already exists, cannot create: <path>error field
Edit empty old_string after a missThe 'old_string' parameter is required. The Edit tool performs localized search-and-replace. ...error field, correction path only
Write target is a directoryPath is a directory, not a file: <path> at validation; Target is a directory, not a file: <path> (EISDIR) at writeValidation error; error field
Write permission or spacePermission denied writing to file: <path> (EACCES); No space left on device: <path> (ENOSPC)error field
Write omission placeholder`content` contains an omission placeholder (for example 'rest of methods ...'). Provide complete file content.Validation error
Stale fileNone. Not detected outside the optional correction path
Command exit non-zeroOutput: <text> then Exit Code: <n>Success text
Command timeoutCommand was automatically cancelled because it exceeded the timeout of <n> minutes without output. plus the output clauseSuccess text
Command cancelledCommand was cancelled by user before it could complete. plus the output clauseSuccess text
Command spawn failureOutput: <text> then Error: <message>error field with type shell_execute_error
Command substitutionCommand injection detected: command substitution syntax ... the command was blocked.Success text
Policy deniedTool execution denied by policy. followed by the rule's denyMessage when one is seterror field with type policy_violation
User rejected at confirmation[Operation Cancelled] Reason: User denied execution.; the rest of the batch gets [Operation Cancelled] Reason: User cancelled operationerror field, status cancelled
Empty commandCommand cannot be empty.Validation error
Sandbox denialSandbox expansion requirederror field with a JSON request in the message
Search path errorsPath does not exist: <path>; Path is not a valid directory or file: <path>; Search path does not exist <path>; Search path is not a directory: <path>Validation error or error field
Grep timeoutOperation timed out after <n>ms. In large repositories, consider narrowing your search scope by specifying a 'dir_path' or an 'include_pattern'.error field
Invalid regexInvalid regular expression pattern provided: <pattern>. Error: <message>Validation error
Directory listing errorsError: Path is not a directory: <path>; Error listing directory: <message>error field
Background logAccess denied. Background process ID <pid> not found in this session's history.; No output log found for process ID <pid>. ...; the symlink denial aboveerror field

Every tool returns a ToolResult. When error is set, the executor sends { error: <error.message> } and discards llmContent; when it is not set, the model receives { output: <llmContent> } or the media parts. Validation failures from validateToolParamValues become Error: Invalid parameters provided. Reason: <message> with type invalid_tool_params. Typed ToolErrorType values stay in the host result and telemetry.

On this page