github/github-mcp-server · info
failed to marshal response: %w
Error message
failed to marshal response: %w
What it means
Returned by listProjects when json.Marshal fails on the response map containing minimalProjects and pageInfo. The MinimalProject values are plain structs of strings, ints, pointers, and time.Time — all JSON-serializable — so in practice this error is near-unreachable; it exists to satisfy error handling. If it ever fires, a struct field of an unmarshalable type (chan, func, complex, or a marshal-time error from a custom MarshalJSON) is the cause.
Source
Thrown at pkg/github/projects.go:1109
// For specified owner_type, process normally
if ownerType != "" {
defer func() { _ = resp.Body.Close() }()
for _, project := range projects {
mp := convertToMinimalProject(project)
mp.OwnerType = ownerType
minimalProjects = append(minimalProjects, *mp)
}
response := map[string]any{
"projects": minimalProjects,
"pageInfo": buildPageInfo(resp),
}
r, err := json.Marshal(response)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to marshal response: %w", err)
}
return utils.NewToolResultText(string(r)), projectVisibilities(minimalProjects), nil, nil
}
return nil, nil, nil, fmt.Errorf("unexpected state in listProjects")
}
// listProjectsFromBothOwnerTypes fetches projects from both user and org endpoints
// when owner_type is not specified, combining the results with owner_type labels.
func listProjectsFromBothOwnerTypes(ctx context.Context, client *github.Client, owner string, opts *github.ListProjectsOptions) (*mcp.CallToolResult, []bool, any, error) {
var minimalProjects []MinimalProject
var resp *github.Response
// Fetch user projects
userProjects, userResp, userErr := client.Projects.ListUserProjects(ctx, owner, opts)
if userErr == nil && userResp.StatusCode == http.StatusOK {
for _, project := range userProjects {View on GitHub (pinned to 0ea1f775a7)
Solutions
- If you are a server contributor: check the failing struct for func/chan/complex fields or custom MarshalJSON methods and fix the type
- As a tool caller: capture the full error (it wraps the json error with type details) and report it as a server-side bug; retrying with different arguments will not help
- Pin/upgrade to a released server version where the regression is not present
- If NaN/Inf may enter floats, sanitize them before they reach the response struct
Defensive patterns
Strategy: try-catch
Try / catch
result, vis, resp, err := listProjects(ctx, client, owner, opts)
if err != nil {
if errors.Is(err, errJSONMarshalPrefix) || strings.Contains(err.Error(), "failed to marshal response") {
// internal serialization defect: do not retry; capture server version and report
reportServerBug(err)
return err
}
return err
} Prevention
- Treat 'failed to marshal response' as a server bug, not an input problem — don't retry with mutated args
- Keep a marshal smoke test (json.Marshal on sample response structs) in CI when contributing response types
- Pin known-good server versions in deployment to isolate regressions
When it happens
Trigger: A MinimalProject field gaining a chan/func/complex type or a custom MarshalJSON that returns an error; unsupported NaN/Inf in a float field (json.Marshal rejects those); a cyclic pointer structure introduced by refactoring.
Common situations: Contributors extending MinimalProject with non-serializable fields during feature work; embedding time values that a custom marshaller chokes on for zero dates. End users essentially never see this from argument input.
Related errors
- 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
- failed to marshal workflow: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/d8ffde68b61c7305.
Report an issue: GitHub.