Why your Gemini CLI skill or subagent never activates
A skill in Gemini CLI is a SKILL.md file, usually in its own folder. At startup, the CLI reads the name and description from every skill it finds and puts that metadata into the system prompt. The body is not loaded until the model calls the activate_skill tool, or you run the skill's slash command, and you approve access to its folder.
A subagent is a separate agent loop exposed as a tool: its own system prompt (the body of a definition file), tool list, and context window. The main session sees its name, description, and result.
Both fail in two places: the thing was never loaded, or it was loaded and nothing chose it. The list commands tell you which.
Run gemini --version first. This was checked against v0.65.0, the stable release on 20 October 2026, and the source at commit 363a131 on 26 October 2026.
Checked against Gemini CLI's documentation on 27 October 2026.
Status, 27 October 2026: interactive sessions register enabled non-built-in skills as slash commands, but a report says the same form fails in non-interactive gemini -p (#21165, open, updated 25 October 2026). Nested skill and agent folders are still not scanned (#21653, closed as not planned on 29 July 2026). Unpaid-tier and Google One users were moved to Antigravity CLI on 18 June 2026, so this page applies to paid, API-key, Vertex AI and enterprise installs; the Gemini CLI hub has the details.
Start with the lists#
Inside a session, /skills list all and /agents list are the dividing line.
/skills list hides built-ins unless you pass all. With no skills of your own, it can say "No skills available" while the built-ins (skill-creator and antigravity-support at v0.65.0) are loaded.
/agents list shows only registered, enabled agents. A file that failed to parse, awaits acknowledgement, is disabled in settings, or sits outside a scanned folder does not appear; a parse error also prints an error line.
From a shell, gemini skills list --all prints each skill's name, state, description, and location. The location tells you which copy won.
| What you see | What it usually means | First check |
|---|---|---|
Skill absent from /skills list all | Discovery: path, filename, frontmatter, trust | gemini skills list --all, then the debug console |
| Skill listed, model ignores it | Selection: the description | Run the skill by its slash command |
Agent absent from /agents list | Discovery, schema, trust, or acknowledgement | /agents reload and the error text |
| Agent listed but never called | Selection: the description | Start the prompt with @name |
If both lists are empty, check skills.enabled (default true) and skills.disabled in /settings or ~/.gemini/settings.json. Both need a restart.
Where a skill has to live#
Gemini CLI discovers skills from four tiers, lowest precedence first: built-in, extension, user (~/.gemini/skills and ~/.agents/skills), and workspace (.gemini/skills and .agents/skills). The skills page and the skill manager source agree on the order, and the higher tier wins when two skills share a name.
Workspace skills are gated by folder trust. If trust is enabled and the folder is untrusted, workspace skills are skipped without a visible warning; only the debug log says so. User skills still load. Folder trust is controlled by security.folderTrust.enabled; the settings reference lists true as the default while the trusted-folders page says the feature must be enabled. Check /permissions trust rather than assuming.
The scan is flat and one level deep. The skill loader looks for SKILL.md and */SKILL.md under each root. This works:
.gemini/skills/
migration-review/
SKILL.mdThis does not:
.gemini/skills/
backend/
migration-review/
SKILL.mdNested support was closed as not planned (#21653), so flatten the directory.
The filename is exact: SKILL.md, not skill.md, and case matters on a case-sensitive filesystem. The folder name is only a container: the frontmatter name is what /skills list shows and what you type after /. A folder called migration-review with name: db-review becomes /db-review.
Why a skill file is skipped#
Frontmatter must start on the first line, open and close with ---, and contain name and description as strings:
---
name: migration-review
description: Reviews database migrations in packages/db. Use when a migration file changes or a migration fails.
---A blank line above the opening ---, or a missing name or description, means the file is skipped.
The failure is quiet: the warning was moved to the debug log in January 2026 (#16140, closed as completed). Run gemini --debug, press F12 for the debug console, and look for the loader's message; the list command will simply omit the file.
A single-line description used to break discovery; that was fixed in October 2026 (#25693).
A skill that is listed but never chosen#
Before activation, the model sees only the name, description, and location. The body is not in the prompt, so the description is a routing rule, not a summary.
Too vague:
description: Helps with migrations.More likely to trigger:
description: Reviews database migrations in packages/db. Use when a migration file changes, a migration fails, or the user asks about rollback risk.The skills page describes the lifecycle: the model matches the task, calls activate_skill, you approve, and the body plus the skill's folder are added to the conversation. If you deny the confirmation, nothing is added.
At the commit I read, every enabled non-built-in skill is also a slash command, registered by the skill command loader. /migration-review activates it and submits the rest of the line. If it is missing, the skill is probably built-in, came from an extension (its command is prefixed with the extension name), or its name collided with a built-in command; otherwise run /skills reload and restart.
Do not treat a sentence from the model as proof. The evidence is an activate_skill tool call, then the confirmation dialog and the body. Reading SKILL.md with an ordinary file tool is not activation either: the text arrives, but the skill is not active and its folder is not added to the allowed paths.
If discovery returns no enabled skills, Gemini CLI removes the activate_skill tool entirely. A model with no skills cannot offer to use one, even if you paste the path to a SKILL.md file.
A skill is not a permission rule: hard requirements belong in the policy engine, which the permissions guide covers.
Where a subagent has to live#
A custom subagent is one Markdown file in .gemini/agents/ or ~/.gemini/agents/. There is no .agents/agents alias, and Gemini CLI does not read .claude/agents; the subagents page gives the two supported paths.
The directory is flat. The agent loader reads the files directly in the directory, skips anything that is not a file, skips names that start with _, and requires a lowercase .md ending. A file in .gemini/agents/review/security.md is never loaded.
A minimal local agent:
---
name: migration-reviewer
description: Reviews database migrations in packages/db. Use when a migration file changes or a migration fails.
tools:
- read_file
- grep_search
---
You review database migrations. Report locking and rollback risks; do not edit files.name must be lowercase letters, numbers, hyphens, or underscores. description is required. The body becomes the system prompt. If you omit tools, the agent inherits every tool from the main session; if you list tools, it gets only those.
The schema rejects unknown keys. An extra field fails with a message such as Validation failed: Agent Definition: Unrecognized key(s) in object: 'mcpServers'. The docs' table and inline-server example both say mcpServers; the loader expects mcp_servers. The report was closed without a fix (#26015), and the page still had the wrong spelling at the commit I read.
Project agents have two gates that user agents do not.
Folder trust. In an untrusted folder, project agents are skipped with "Skipping project agents due to untrusted folder"; user agents still load.
Acknowledgement. A project agent is not registered until you accept it (the registry). On first sight the CLI shows a "New Agents Discovered" dialog (the dialog) with "Acknowledge and Enable" and "Do not enable (Ask again next time)". The acceptance is stored in ~/.gemini/acknowledgments/agents.json, keyed to the file's content hash. Edit the file and the hash changes, so the next start or /agents reload asks again. Until you accept, the agent is not in /agents list and cannot be called. The subagents page describes discovery but not this step.
A subagent that is listed but never called#
The main agent chooses an agent from its description. The docs say the model decides whether an agent is a relevant expert based on that description. Write it as a trigger, with the area, the task, and the situations that should call it. "Security expert" is weaker than "Reviews authentication and authorization changes in packages/api. Use when a route, middleware, or permission check changes."
@name is the manual path, but it is a nudge rather than an override. When the name matches a registered agent, Gemini CLI appends a system note that names the agent and asks the model to delegate; the model still makes the call. When the name does not match, the @ is handled as a file reference, not a delegation.
experimental.enableAgents: false disables all subagents, including built-ins, and leaves /agents list empty (the settings reference). agents.overrides.<name>.enabled: false removes one agent from the registry, so it does not appear and cannot be chosen.
A subagent cannot call another subagent. The docs call this recursion protection: even an agent with the * tool wildcard cannot see or invoke other agents. If your design is "the reviewer hands off to the fixer", that handoff has to happen in the main session.
Skills inside subagents have their own limit. A subagent's system prompt gets the skill list only if activate_skill is in its tool registry, which happens when tools is omitted or includes it. A subagent restricted to read_file and grep_search has no skill catalogue and cannot activate anything. Per-agent skill scoping and forced skills are still a request (#18276, open).
If you copied these from Claude Code#
- Paths. Claude Code reads
~/.claude/skills,.claude/skills, and.claude/agents; Gemini CLI reads none of those. Put skills in~/.gemini/skills,~/.agents/skills,.gemini/skills, or.agents/skills, and agents in~/.gemini/agentsor.gemini/agents. - Depth. Claude Code scans
.claude/agentsrecursively; Gemini CLI reads only files directly in.gemini/agents. - Unknown fields. Claude Code ignores unknown frontmatter; Gemini CLI's agent schema rejects the file. A Claude Code agent copied here with
permissionMode,disallowedTools, ormaxTurnsdoes not load; the Gemini spelling ismax_turns. - Tools. Claude Code's
tools: Read, Grep, Globuses Claude tool names and accepts that comma-separated form (or a YAML list); Gemini CLI requires a YAML list of its own names (read_file,grep_search,glob).
Skills travel better than agents. Gemini CLI's skill parser reads only name and description and ignores the rest of the frontmatter, so a Claude Code skill with both fields usually works once it is in a folder Gemini CLI scans. The body may still use Claude-only substitutions or ! commands that Gemini CLI does not run.
Where to go next#
- Gemini CLI guides — the rest of the set: instructions, sessions, permissions, memory, and hooks.
- Why Gemini CLI keeps asking for permission — when the problem is approval or a policy rule rather than discovery.
- What a Claude Code subagent can and can't see — if you are moving a subagent design across tools.