github/github-mcp-server · warning

failed to read docs file

Error message

failed to read docs file: %w

What it means

Returned by rewriteAutomatedSection in the feature-flag docs generator when os.ReadFile(path) fails. This is a maintainer/CI codegen command (cmd/github-mcp-server feature-flag docs) that rewrites a marked section of a markdown file; the read fails when the file does not exist at the expected path or is not readable by the current user.

Solutions

  1. Run the command from the repository root so relative doc paths resolve
  2. Verify the target file exists (ls docs/…) and matches the path passed to the generator
  3. Fix file permissions if unreadable (chmod/chown)
  4. If docs were restructured, update the hardcoded/default path in feature_flag_docs.go
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the docs file exists before invoking the generator
if _, err := os.Stat(docsPath); err != nil {
    log.Fatalf("docs file missing: %s", docsPath)
}
_ = rewriteDocs(docsPath)

Try / catch

if err := rewriteAutomatedSection(path, start, end, body); err != nil {
    if os.IsNotExist(err) || strings.Contains(err.Error(), "failed to read docs file") {
        log.Fatalf("docs file not found at %s — run from repo root", path)
    }
    return err
}

Prevention

When it happens

Trigger: Running the feature-flag docs generation command from a directory other than the repo root so the relative docs path does not resolve; the target markdown file was deleted or renamed; file permissions deny read access; a custom --path flag pointing at a nonexistent file.

Common situations: CI jobs that check out only a subset of the repo; running `go run ./cmd/github-mcp-server` from a subdirectory; docs restructured without updating the codegen paths.

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/2016f156ffc7ee23. Report an issue: GitHub.

Appendix: source

Thrown at cmd/github-mcp-server/feature_flag_docs.go:132

// (e.g. flag-gated dual registrations), the first occurrence wins, mirroring
// AvailableTools' deterministic sort order.
func indexToolsByName(tools []inventory.ServerTool) map[string]inventory.ServerTool {
	out := make(map[string]inventory.ServerTool, len(tools))
	for _, tool := range tools {
		if _, ok := out[tool.Tool.Name]; ok {
			continue
		}
		out[tool.Tool.Name] = tool
	}
	return out
}

// rewriteAutomatedSection reads a markdown file, replaces the content between
// the named markers with body, and writes it back.
func rewriteAutomatedSection(path, startMarker, endMarker, body string) error {
	content, err := os.ReadFile(path) //#nosec G304
	if err != nil {
		return fmt.Errorf("failed to read docs file: %w", err)
	}
	updated, err := replaceSection(string(content), startMarker, endMarker, body)
	if err != nil {
		return err
	}
	return os.WriteFile(path, []byte(updated), 0600) //#nosec G306
}

View on GitHub (pinned to 0ea1f775a7)