{"record":{"id":"e05b0786e3e34c62","repo":"github/github-mcp-server","slug":"failed-to-marshal-workflows-w","errorCode":null,"errorMessage":"failed to marshal workflows: %w","messagePattern":"failed to marshal workflows: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/actions.go","lineNumber":839,"sourceCode":"\t}\n\treturn utils.NewToolResultText(string(r)), nil, nil\n}\n\nfunc listWorkflows(ctx context.Context, client *github.Client, owner, repo string, pagination PaginationParams) (*mcp.CallToolResult, any, error) {\n\topts := &github.ListOptions{\n\t\tPerPage: pagination.PerPage,\n\t\tPage:    pagination.Page,\n\t}\n\n\tworkflows, resp, err := client.Actions.ListWorkflows(ctx, owner, repo, opts)\n\tif err != nil {\n\t\treturn ghErrors.NewGitHubAPIErrorResponse(ctx, \"failed to list workflows\", resp, err), nil, nil\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tr, err := json.Marshal(workflows)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to marshal workflows: %w\", err)\n\t}\n\n\treturn utils.NewToolResultText(string(r)), nil, nil\n}\n\nfunc listWorkflowRuns(ctx context.Context, client *github.Client, args map[string]any, owner, repo, resourceID string, pagination PaginationParams) (*mcp.CallToolResult, any, error) {\n\tfilterArgs, err := OptionalParam[map[string]any](args, \"workflow_runs_filter\")\n\tif err != nil {\n\t\treturn utils.NewToolResultError(err.Error()), nil, nil\n\t}\n\n\tfilterArgsTyped := make(map[string]string)\n\tfor k, v := range filterArgs {\n\t\tif strVal, ok := v.(string); ok {\n\t\t\tfilterArgsTyped[k] = strVal\n\t\t} else {\n\t\t\tfilterArgsTyped[k] = \"\"\n\t\t}","sourceCodeStart":821,"sourceCodeEnd":857,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/actions.go#L821-L857","documentation":"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.","triggerScenarios":"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.","commonSituations":"Not seen with stock releases; appears in heavily forked servers or with replace-directive go-github builds.","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"],"exampleFix":"// before\nr, err := json.Marshal(workflows)\nif err != nil {\n    return nil, nil, fmt.Errorf(\"failed to marshal workflows: %w\", err)\n}\n\n// after - include count context to speed up diagnosis\nr, err := json.Marshal(workflows)\nif err != nil {\n    return nil, nil, fmt.Errorf(\"failed to marshal workflows (count=%d): %w\", len(workflows.Workflows), err)\n}","handlingStrategy":"validation","validationCode":"// Test-side guard over list responses\nfunc TestWorkflowListMarshal(t *testing.T) {\n    if _, err := json.Marshal(&github.WorkflowList{}); err != nil {\n        t.Fatalf(\"workflow list not JSON-safe: %v\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    reportIssue(\"list_action_workflows\", map[string]any{\"owner\": owner, \"repo\": repo}, err, version())\n    return err\n}","preventionTips":["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"],"tags":["json","serialization","workflow","pagination","go"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}