github/github-mcp-server · error

invalid detail %q: must be one of "none", "stats", "full_pat

Error message

invalid detail %q: must be one of "none", "stats", "full_patch"

What it means

Thrown by parseCommitDetail in pkg/github/minimal_types.go when a tool's 'detail' argument is not one of the allowed values "none", "stats", or "full_patch". The commit tools (get_commit, list_commits in repositories.go) use it to select how much of a commit to return. An empty string is valid and defaults to "stats", so this error only fires on a non-empty wrong value.

Source

Thrown at pkg/github/minimal_types.go:1780

	// commitDetailNone omits Stats and Files entirely.
	commitDetailNone commitDetail = "none"
	// commitDetailStats includes Stats and Files with metadata only
	// (filename, status, additions, deletions, changes) but no patch text.
	commitDetailStats commitDetail = "stats"
	// commitDetailFullPatch additionally includes the unified diff for each file.
	commitDetailFullPatch commitDetail = "full_patch"
)

// parseCommitDetail validates the user-supplied detail value and returns the
// default (stats) when the value is empty.
func parseCommitDetail(s string) (commitDetail, error) {
	switch s {
	case "":
		return commitDetailStats, nil
	case string(commitDetailNone), string(commitDetailStats), string(commitDetailFullPatch):
		return commitDetail(s), nil
	default:
		return "", fmt.Errorf("invalid detail %q: must be one of \"none\", \"stats\", \"full_patch\"", s)
	}
}

func convertToMinimalCommit(commit *github.RepositoryCommit, detail commitDetail) MinimalCommit {
	minimalCommit := newMinimalCommitFromCore(
		commit.GetSHA(),
		commit.GetHTMLURL(),
		commit.Commit,
		commit.Author,
		commit.Committer,
	)

	if detail == commitDetailNone {
		return minimalCommit
	}

	if commit.Stats != nil {
		minimalCommit.Stats = &MinimalCommitStats{

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Set detail to one of "none", "stats", or "full_patch" (exact lowercase, with underscore).
  2. Omit the detail argument entirely to get the default "stats" behavior.
  3. If you need the raw diff/patch content, use detail "full_patch"; if you need no files at all, use "none".
  4. Re-read the tool's inputSchema returned by tools/list — the enum there is the source of truth for your server version.

Example fix

// before
github.callTool({ name: "get_commit", arguments: { owner, repo, sha, detail: "full" } });
// after
github.callTool({ name: "get_commit", arguments: { owner, repo, sha, detail: "full_patch" } });
Defensive patterns

Strategy: validation

Validate before calling

const COMMIT_DETAILS = ["none", "stats", "full_patch"];
function validDetail(d) {
  return d === undefined || d === null || COMMIT_DETAILS.includes(d);
}
// before calling get_commit/list_commits:
if (!validDetail(args.detail)) {
  throw new Error(`detail must be one of ${COMMIT_DETAILS.join(", ")} or omitted`);
}

Type guard

function isCommitDetail(v: unknown): v is "none" | "stats" | "full_patch" | undefined {
  return v === undefined || v === "none" || v === "stats" || v === "full_patch";
}

Try / catch

In MCP clients the tool call returns an error result rather than throwing: check result.isError and match /invalid detail/ in the message, then re-ask the model/user with the allowed enum listed.

Prevention

When it happens

Trigger: Calling the get_commit or list_commits MCP tool with detail set to anything except "none"/"stats"/"full_patch" — e.g. detail="patches", detail="full", detail="FULL_PATCH", or a number/boolean instead of a string.

Common situations: Typing "full" instead of "full_patch"; assuming the API mirrors GitHub REST's verbose diff modes; casing mistakes; older workflows written before the detail argument accepted "full_patch"; passing a value copied from a different tool's schema.

Related errors


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