{"record":{"id":"f3cddb92bf4f3fe0","repo":"google-gemini/gemini-cli","slug":"could-not-read-file-geterrormessage-error","errorCode":null,"errorMessage":"Could not read file: ${getErrorMessage(error)}","messagePattern":"Could not read file: (.+?)","errorType":"exception","errorClass":"AgentLoadError","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/agentLoader.ts","lineNumber":340,"sourceCode":" * Parses and validates an agent Markdown file with frontmatter.\n *\n * @param filePath Path to the Markdown file.\n * @param content Optional pre-loaded content of the file.\n * @returns An array containing the single parsed agent definition.\n * @throws AgentLoadError if parsing or validation fails.\n */\nexport async function parseAgentMarkdown(\n  filePath: string,\n  content?: string,\n): Promise<FrontmatterAgentDefinition[]> {\n  let fileContent: string;\n  if (content !== undefined) {\n    fileContent = content;\n  } else {\n    try {\n      fileContent = await fs.readFile(filePath, 'utf-8');\n    } catch (error) {\n      throw new AgentLoadError(\n        filePath,\n        `Could not read file: ${getErrorMessage(error)}`,\n      );\n    }\n  }\n\n  // Split frontmatter and body\n  const match = fileContent.match(FRONTMATTER_REGEX);\n  if (!match) {\n    throw new AgentLoadError(\n      filePath,\n      '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---).',\n    );\n  }\n\n  const frontmatterStr = match[1];\n  const body = match[2] || '';\n","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/agentLoader.ts#L322-L358","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the file exists at the absolute path recorded on the AgentLoadError.","Run `ls -l <filePath>` to verify read permission for the current process.","If the path is relative, resolve it against the configured agents directory, not process cwd.","Remove or fix broken symlinks in the agents directory."],"exampleFix":"// before\nawait parseAgentMarkdown('./agents/researcher.md');\n\n// after\nimport { access } from 'node:fs/promises';\nawait access(filePath, constants.R_OK).catch(() => {\n  throw new Error(`Agent file missing or unreadable: ${filePath}`);\n});\nawait parseAgentMarkdown(filePath);","handlingStrategy":"validation","validationCode":"import { access, constants } from 'node:fs/promises';\nasync function ensureReadable(path: string): Promise<void> {\n  await access(path, constants.R_OK);\n}\nawait ensureReadable(filePath);\nconst defs = await parseAgentMarkdown(filePath);","typeGuard":null,"tryCatchPattern":"try {\n  return await parseAgentMarkdown(filePath);\n} catch (e) {\n  if (e instanceof AgentLoadError && /Could not read file/.test(e.message)) {\n    // missing/unreadable - skip or surface clearly\n  }\n  throw e;\n}","preventionTips":["Glob agent files and access-check each before parsing.","Use absolute paths rooted at the configured agents directory.","Watch for symlink breakage after checkouts."],"tags":["filesystem","agent-loader","io","permissions"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}