google-gemini/gemini-cli · error · AgentLoadError

Could not read file: ${getErrorMessage(error)}

Error message

Could not read file: ${getErrorMessage(error)}

What it means

parseAgentMarkdown wraps fs.readFile failures in an AgentLoadError, surfacing the OS-level message (ENOENT, EACCES, EISDIR, etc.) via getErrorMessage. The filePath is preserved on the error so loaders can attribute the failure. This is the outermost I/O guard before frontmatter parsing begins.

Source

Thrown at packages/core/src/agents/agentLoader.ts:340

 * Parses and validates an agent Markdown file with frontmatter.
 *
 * @param filePath Path to the Markdown file.
 * @param content Optional pre-loaded content of the file.
 * @returns An array containing the single parsed agent definition.
 * @throws AgentLoadError if parsing or validation fails.
 */
export async function parseAgentMarkdown(
  filePath: string,
  content?: string,
): Promise<FrontmatterAgentDefinition[]> {
  let fileContent: string;
  if (content !== undefined) {
    fileContent = content;
  } else {
    try {
      fileContent = await fs.readFile(filePath, 'utf-8');
    } catch (error) {
      throw new AgentLoadError(
        filePath,
        `Could not read file: ${getErrorMessage(error)}`,
      );
    }
  }

  // Split frontmatter and body
  const match = fileContent.match(FRONTMATTER_REGEX);
  if (!match) {
    throw new AgentLoadError(
      filePath,
      'Invalid agent definition: Missing mandatory YAML frontmatter. Agent Markdown files MUST start with YAML frontmatter enclosed in triple-dashes "---" (e.g., ---\nname: my-agent\n---).',
    );
  }

  const frontmatterStr = match[1];
  const body = match[2] || '';

View on GitHub (pinned to 5024443c72)

Solutions

  1. Confirm the file exists at the absolute path recorded on the AgentLoadError.
  2. Run `ls -l <filePath>` to verify read permission for the current process.
  3. If the path is relative, resolve it against the configured agents directory, not process cwd.
  4. Remove or fix broken symlinks in the agents directory.

Example fix

// before
await parseAgentMarkdown('./agents/researcher.md');

// after
import { access } from 'node:fs/promises';
await access(filePath, constants.R_OK).catch(() => {
  throw new Error(`Agent file missing or unreadable: ${filePath}`);
});
await parseAgentMarkdown(filePath);
Defensive patterns

Strategy: validation

Validate before calling

import { access, constants } from 'node:fs/promises';
async function ensureReadable(path: string): Promise<void> {
  await access(path, constants.R_OK);
}
await ensureReadable(filePath);
const defs = await parseAgentMarkdown(filePath);

Try / catch

try {
  return await parseAgentMarkdown(filePath);
} catch (e) {
  if (e instanceof AgentLoadError && /Could not read file/.test(e.message)) {
    // missing/unreadable - skip or surface clearly
  }
  throw e;
}

Prevention

When it happens

Trigger: The agent .md path does not exist (ENOENT); the process lacks read permission (EACCES); the path resolves to a directory (EISDIR); a symlink is broken; the path is relative and the cwd changed; disk/network filesystem unmounted.

Common situations: agents glob expanded to a path that was deleted; a config entry points to a file outside the project; permission bits changed after a deploy; case-sensitive filesystem mismatch from a cross-platform checkout.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/f3cddb92bf4f3fe0. Report an issue: GitHub.