github/github-mcp-server · error
failed to marshal workflows: %w
Error message
failed to marshal workflows: %w
What it means
Defensive guard in listWorkflows (pkg/github/actions.go:839): json.Marshal of the *github.WorkflowList (the whole workflows array from ListWorkflows) failed. The list is server-produced JSON-safe data, so this is effectively unreachable except through a regression introducing non-serializable values; the body is closed via defer before marshal, so it is purely a serialization guard.
Source
Thrown at pkg/github/actions.go:839
}
return utils.NewToolResultText(string(r)), nil, nil
}
func listWorkflows(ctx context.Context, client *github.Client, owner, repo string, pagination PaginationParams) (*mcp.CallToolResult, any, error) {
opts := &github.ListOptions{
PerPage: pagination.PerPage,
Page: pagination.Page,
}
workflows, resp, err := client.Actions.ListWorkflows(ctx, owner, repo, opts)
if err != nil {
return ghErrors.NewGitHubAPIErrorResponse(ctx, "failed to list workflows", resp, err), nil, nil
}
defer func() { _ = resp.Body.Close() }()
r, err := json.Marshal(workflows)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal workflows: %w", err)
}
return utils.NewToolResultText(string(r)), nil, nil
}
func listWorkflowRuns(ctx context.Context, client *github.Client, args map[string]any, owner, repo, resourceID string, pagination PaginationParams) (*mcp.CallToolResult, any, error) {
filterArgs, err := OptionalParam[map[string]any](args, "workflow_runs_filter")
if err != nil {
return utils.NewToolResultError(err.Error()), nil, nil
}
filterArgsTyped := make(map[string]string)
for k, v := range filterArgs {
if strVal, ok := v.(string); ok {
filterArgsTyped[k] = strVal
} else {
filterArgsTyped[k] = ""
}View on GitHub (pinned to 0ea1f775a7)
Solutions
- Report upstream with repository and versions if hit with stock code
- Pin dependencies to known-good versions
- If maintaining a fork, keep PaginationParams sane and avoid injecting custom objects into results
- Add a marshal test over representative list responses
Example fix
// before
r, err := json.Marshal(workflows)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal workflows: %w", err)
}
// after - include count context to speed up diagnosis
r, err := json.Marshal(workflows)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal workflows (count=%d): %w", len(workflows.Workflows), err)
} Defensive patterns
Strategy: validation
Validate before calling
// Test-side guard over list responses
func TestWorkflowListMarshal(t *testing.T) {
if _, err := json.Marshal(&github.WorkflowList{}); err != nil {
t.Fatalf("workflow list not JSON-safe: %v", err)
}
} Try / catch
if err != nil {
reportIssue("list_action_workflows", map[string]any{"owner": owner, "repo": repo}, err, version())
return err
} Prevention
- Pin dependency versions in production
- Add marshal smoke tests for list endpoints
- Do not retry deterministic serialization failures
- When forking, keep result payloads free of non-serializable types
When it happens
Trigger: Calling list_action_workflows after a dependency change that makes Workflow or WorkflowList unmarshalable; huge result sets are not a failure cause - json.Marshal handles arbitrary size, only value types matter.
Common situations: Not seen with stock releases; appears in heavily forked servers or with replace-directive go-github builds.
Related errors
- failed to marshal workflow: %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/e05b0786e3e34c62.
Report an issue: GitHub.