{"record":{"id":"2558378e61bcb58d","repo":"github/github-mcp-server","slug":"failed-to-marshal-workflow-runs-w","errorCode":null,"errorMessage":"failed to marshal workflow runs: %w","messagePattern":"failed to marshal workflow runs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/actions.go","lineNumber":889,"sourceCode":"\tvar workflowRuns *github.WorkflowRuns\n\tvar resp *github.Response\n\n\tif resourceID == \"\" {\n\t\tworkflowRuns, resp, err = client.Actions.ListRepositoryWorkflowRuns(ctx, owner, repo, listWorkflowRunsOptions)\n\t} else if workflowIDInt, parseErr := strconv.ParseInt(resourceID, 10, 64); parseErr == nil {\n\t\tworkflowRuns, resp, err = client.Actions.ListWorkflowRunsByID(ctx, owner, repo, workflowIDInt, listWorkflowRunsOptions)\n\t} else {\n\t\tworkflowRuns, resp, err = client.Actions.ListWorkflowRunsByFileName(ctx, owner, repo, resourceID, listWorkflowRunsOptions)\n\t}\n\n\tif err != nil {\n\t\treturn ghErrors.NewGitHubAPIErrorResponse(ctx, \"failed to list workflow runs\", resp, err), nil, nil\n\t}\n\n\tdefer func() { _ = resp.Body.Close() }()\n\tr, err := json.Marshal(convertToMinimalWorkflowRuns(workflowRuns))\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to marshal workflow runs: %w\", err)\n\t}\n\n\treturn utils.NewToolResultText(string(r)), nil, nil\n}\n\nfunc listWorkflowJobs(ctx context.Context, client *github.Client, args map[string]any, owner, repo string, resourceID int64, pagination PaginationParams) (*mcp.CallToolResult, any, error) {\n\tfilterArgs, err := OptionalParam[map[string]any](args, \"workflow_jobs_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":871,"sourceCodeEnd":907,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/actions.go#L871-L907","documentation":"json.Marshal failed while serializing the trimmed workflow-run list produced by convertToMinimalWorkflowRuns after a successful ListWorkflowRunsByID/ListWorkflowRunsByFileName call. encoding/json only fails on values it cannot represent: channels, functions, complex numbers, cyclic data structures, or float NaN/Inf (json.UnsupportedTypeError / json.UnsupportedValueError). Because the payload is maps/structs of strings, ints and timestamps built from go-github types, this branch is defensive and should never fire on a healthy release.","triggerScenarios":"Calling list_workflow_runs (or list_workflow_runs_by_filename) and reaching the final json.Marshal with a payload containing a non-JSON-representable value — e.g. an upstream go-github version bump that added a func/chan/complex-typed field copied through the minimal-runs converter, or a fork that passes timestamps.Float64 values that are NaN.","commonSituations":"Pinned/old go-github dependency whose structs diverge from the API payload, custom forks extending convertToMinimalWorkflowRuns with unsupported types, or corrupted in-memory data after a partial API response.","solutions":["Inspect the wrapped error: json.UnsupportedTypeError names the exact Go type and field path that broke marshaling — fix or stringify that field in convertToMinimalWorkflowRuns","Update the go-github dependency and github-mcp-server to matching versions so the struct shape matches what GitHub returns","Sanitize the converted runs before marshaling (drop or fmt.Sprintf non-JSON types, clamp NaN/Inf floats)","Re-run the tool once to rule out a one-off corrupted response"],"exampleFix":"// before\nr, err := json.Marshal(convertToMinimalWorkflowRuns(workflowRuns))\nif err != nil {\n\treturn nil, nil, fmt.Errorf(\"failed to marshal workflow runs: %w\", err)\n}\n\n// after — surface the offending type and return a tool-safe error\nruns := convertToMinimalWorkflowRuns(workflowRuns)\nr, err := json.Marshal(runs)\nif err != nil {\n\tvar unsupported *json.UnsupportedTypeError\n\tif errors.As(err, &unsupported) {\n\t\tslog.Error(\"unmarshalable workflow run payload\", \"type\", unsupported.Type.String())\n\t}\n\treturn utils.NewToolResultError(fmt.Sprintf(\"failed to serialize workflow runs: %v\", err)), nil, nil\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isJSONMarshalable(v any) bool {\n\tswitch v.(type) {\n\tcase chan struct{}, func(), complex128, complex64:\n\t\treturn false\n\t}\n\treturn true\n}","tryCatchPattern":"r, err := json.Marshal(runs)\nif err != nil {\n\tvar unsupported *json.UnsupportedTypeError\n\tvar value *json.UnsupportedValueError\n\tswitch {\n\tcase errors.As(err, &unsupported):\n\t\t// upstream type drift: log unsupported.Type and degrade gracefully\n\tcase errors.As(err, &value):\n\t\t// NaN/Inf: sanitize numeric fields and retry once\n\tdefault:\n\t\treturn fmt.Errorf(\"failed to marshal workflow runs: %w\", err)\n\t}\n}","preventionTips":["Keep go-github and github-mcp-server versions aligned in go.mod — struct drift is the main realistic cause","In forks, restrict converter output to strings, numbers, booleans, and time.Time","Add a unit test asserting convertToMinimalWorkflowRuns output marshals for representative fixtures"],"tags":["go","json","serialization","github-actions","workflow-runs"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}