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
- Diff the MinimalCombinedStatus struct family — look for newly added func, chan, or pointer-cycle fields
- Add a unit test that round-trips a realistic CombinedStatus through convertToMinimalCombinedStatus + json.Marshal
- 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
- Unit-test json round-trips of all Minimal* types in CI
- Never add func/chan fields or cyclic pointers to response structs
- Treat this error as a build/regression signal, not an operational incident
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
- failed to marshal response: %w
- GitHub App authentication and GITHUB_PERSONAL_ACCESS_TOKEN a
- GitHub App ID or client ID is required (GITHUB_APP_ID)
- repo is required
- failed to marshal response: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/88f05ec858653dda.
Report an issue: GitHub.