github/github-mcp-server · warning

failed to marshal response: %w

Error message

failed to marshal response: %w

What it means

get_pull_request_status marshals convertToMinimalCombinedStatus(status) with json.Marshal before returning the tool result. Go's json.Marshal only errors on unsupported types (func, chan, complex), cycles, or NaN/Inf floats — none of which this plain data struct contains. This branch is defensive dead code; if it ever fires it signals a regression in the MinimalCombinedStatus type, not a runtime condition.

Source

Thrown at pkg/github/pullrequests.go:312

		return ghErrors.NewGitHubAPIErrorResponse(ctx,
			"failed to get combined status",
			resp,
			err,
		), nil
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode != http.StatusOK {
		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, fmt.Errorf("failed to read response body: %w", err)
		}
		return ghErrors.NewGitHubAPIStatusErrorResponse(ctx, "failed to get combined status", resp, body), nil
	}

	r, err := json.Marshal(convertToMinimalCombinedStatus(status))
	if err != nil {
		return nil, fmt.Errorf("failed to marshal response: %w", err)
	}

	return utils.NewToolResultText(string(r)), nil
}

func GetPullRequestCheckRuns(ctx context.Context, client *github.Client, owner, repo string, pullNumber int, pagination PaginationParams) (*mcp.CallToolResult, error) {
	// First get the PR to get the head SHA
	pr, resp, err := client.PullRequests.Get(ctx, owner, repo, pullNumber)
	if err != nil {
		return ghErrors.NewGitHubAPIErrorResponse(ctx,
			"failed to get pull request",
			resp,
			err,
		), nil
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Diff the MinimalCombinedStatus struct family — look for newly added func, chan, or pointer-cycle fields
  2. Add a unit test that round-trips a realistic CombinedStatus through convertToMinimalCombinedStatus + json.Marshal
  3. Keep minimal types to plain strings/ints/bools; put derived values in precomputed string fields

Example fix

// before
type MinimalCombinedStatus struct {
	State    string             `json:"state"`
	Statuses []MinimalStatus    `json:"statuses"`
	Filter   func(string) bool  `json:"-"` // json.Marshal never sees func fields with json:"-"... but without the tag it fails
}

// after — keep the type JSON-safe
type MinimalCombinedStatus struct {
	State    string          `json:"state"`
	Statuses []MinimalStatus `json:"statuses"`
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

func isMarshalTypeErr(err error) bool {
	var typeErr *json.UnsupportedTypeError
	var valErr *json.UnsupportedValueError
	return errors.As(err, &typeErr) || errors.As(err, &valErr)
}

Try / catch

r, err := json.Marshal(minimalStatus)
if err != nil {
	// not retryable: log a bug-level alert and return a tool error
deps.Logger(ctx).Error("marshal regression", "err", err)
	return nil, fmt.Errorf("internal serialization failure: %w", err)
}

Prevention

When it happens

Trigger: Someone adds a func-typed, chan-typed, or self-referencing field to MinimalCombinedStatus or its nested types (MinimalStatus/MinimalStatusContext); production data flows through and Marshal returns *json.UnsupportedTypeError or *json.UnsupportedValueError.

Common situations: Refactors of the minimal-types file that add computed getters or callbacks; almost never seen from API data alone because GitHub JSON decodes into plain strings/ints/bools.

Related errors


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