{"record":{"id":"a0ee6b9725cf3611","repo":"github/github-mcp-server","slug":"failed-to-marshal-workflow-jobs-w","errorCode":null,"errorMessage":"failed to marshal workflow jobs: %w","messagePattern":"failed to marshal workflow jobs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/actions.go","lineNumber":928,"sourceCode":"\tworkflowJobs, resp, err := client.Actions.ListWorkflowJobs(ctx, owner, repo, resourceID, &github.ListWorkflowJobsOptions{\n\t\tFilter: filterArgsTyped[\"filter\"],\n\t\tListOptions: github.ListOptions{\n\t\t\tPage:    pagination.Page,\n\t\t\tPerPage: pagination.PerPage,\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn ghErrors.NewGitHubAPIErrorResponse(ctx, \"failed to list workflow jobs\", resp, err), nil, nil\n\t}\n\n\tresponse := map[string]any{\n\t\t\"jobs\": convertToMinimalWorkflowJobs(workflowJobs),\n\t}\n\n\tdefer func() { _ = resp.Body.Close() }()\n\tr, err := json.Marshal(response)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to marshal workflow jobs: %w\", err)\n\t}\n\n\treturn utils.NewToolResultText(string(r)), nil, nil\n}\n\nfunc listWorkflowArtifacts(ctx context.Context, client *github.Client, owner, repo string, resourceID int64, pagination PaginationParams) (*mcp.CallToolResult, any, error) {\n\topts := &github.ListOptions{\n\t\tPerPage: pagination.PerPage,\n\t\tPage:    pagination.Page,\n\t}\n\n\tartifacts, resp, err := client.Actions.ListWorkflowRunArtifacts(ctx, owner, repo, resourceID, opts)\n\tif err != nil {\n\t\treturn ghErrors.NewGitHubAPIErrorResponse(ctx, \"failed to list workflow run artifacts\", resp, err), nil, nil\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tr, err := json.Marshal(artifacts)","sourceCodeStart":910,"sourceCodeEnd":946,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/actions.go#L910-L946","documentation":"json.Marshal failed on the {\"jobs\": convertToMinimalWorkflowJobs(...)} response map built after a successful workflow-jobs listing. encoding/json errors only occur for values it cannot encode (chan, func, complex, cyclic structures, NaN/Inf floats). Since the map holds a slice of trimmed job structs made of strings, ints and timestamps, the failure indicates the converted data contains an unsupported value rather than a GitHub API problem.","triggerScenarios":"Calling list_workflow_jobs for a run and having the minimal-jobs converter emit a non-JSON-representable value — typically after upgrading go-github so a new field of an unsupported type flows through convertToMinimalWorkflowJobs, or a fork adds such a field.","commonSituations":"Dependency drift between go-github and the server's converter functions, custom converters extended with io.Reader or func fields, corrupted pagination data after a truncated API response.","solutions":["Read the wrapped json.UnsupportedTypeError/UnsupportedValueError to find the offending field and type, then drop or stringify it in convertToMinimalWorkflowJobs","Align go-github and github-mcp-server versions so job structs match the live API","Pre-sanitize the jobs slice (only keep string/number/bool/time fields) before marshaling","Retry the call to exclude transient corruption"],"exampleFix":"// before\nresponse := map[string]any{\"jobs\": convertToMinimalWorkflowJobs(workflowJobs)}\nr, err := json.Marshal(response)\nif err != nil {\n\treturn nil, nil, fmt.Errorf(\"failed to marshal workflow jobs: %w\", err)\n}\n\n// after — guard and report without crashing the tool\ndoc := map[string]any{\"jobs\": convertToMinimalWorkflowJobs(workflowJobs)}\nr, err := json.Marshal(doc)\nif err != nil {\n\treturn utils.NewToolResultError(fmt.Sprintf(\"failed to serialize workflow jobs: %v\", err)), nil, nil\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func jobsAreJSONSafe(jobs []map[string]any) bool {\n\tfor _, j := range jobs {\n\t\tfor _, v := range j {\n\t\t\tswitch v.(type) {\n\t\t\tcase chan struct{}, func(), complex128, complex64:\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"r, err := json.Marshal(response)\nif err != nil {\n\tvar unsupported *json.UnsupportedTypeError\n\tif errors.As(err, &unsupported) {\n\t\t// strip or stringify unsupported.Type, rebuild the response map, retry marshal once\n\t}\n\treturn fmt.Errorf(\"failed to marshal workflow jobs: %w\", err)\n}","preventionTips":["Pin a known-good go-github version rather than riding branch heads","Extend convertToMinimalWorkflowJobs with explicit string/int projections instead of passing raw upstream values","Cover converter output with snapshot tests that unmarshal-verify the marshaled JSON"],"tags":["go","json","serialization","github-actions","workflow-jobs"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}