github/github-mcp-server · error

failed to marshal workflow job: %w

Error message

failed to marshal workflow job: %w

What it means

Defensive guard in getWorkflowJob (pkg/github/actions.go:820): json.Marshal of the *github.WorkflowJob returned by GetWorkflowJobByID failed. The go-github WorkflowJob struct is composed of JSON-safe data types, so this branch is effectively unreachable barring a regression that introduces func/chan/NaN/cyclic values.

Source

Thrown at pkg/github/actions.go:820

		return ghErrors.NewGitHubAPIErrorResponse(ctx, "failed to get workflow run", resp, err), nil, nil
	}
	defer func() { _ = resp.Body.Close() }()
	r, err := json.Marshal(convertToMinimalWorkflowRun(workflowRun))
	if err != nil {
		return nil, nil, fmt.Errorf("failed to marshal workflow run: %w", err)
	}
	return utils.NewToolResultText(string(r)), nil, nil
}

func getWorkflowJob(ctx context.Context, client *github.Client, owner, repo string, resourceID int64) (*mcp.CallToolResult, any, error) {
	workflowJob, resp, err := client.Actions.GetWorkflowJobByID(ctx, owner, repo, resourceID)
	if err != nil {
		return ghErrors.NewGitHubAPIErrorResponse(ctx, "failed to get workflow job", resp, err), nil, nil
	}
	defer func() { _ = resp.Body.Close() }()
	r, err := json.Marshal(workflowJob)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to marshal workflow job: %w", err)
	}
	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 {

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Report upstream with arguments and dependency versions
  2. Pin go-github to a version where the tool worked
  3. If patching, marshal an explicit subset of fields
  4. Add marshal coverage to CI

Example fix

// before
r, err := json.Marshal(workflowJob)
if err != nil {
    return nil, nil, fmt.Errorf("failed to marshal workflow job: %w", err)
}

// after - subset DTO decouples the wire format from the go-github struct
r, err := json.Marshal(map[string]any{
    "id": workflowJob.GetID(), "name": workflowJob.GetName(), "status": workflowJob.GetStatus(), "conclusion": workflowJob.GetConclusion(),
})
Defensive patterns

Strategy: validation

Validate before calling

// Test-side guard: ensure the job struct round-trips
func TestWorkflowJobMarshal(t *testing.T) {
    if _, err := json.Marshal(&github.WorkflowJob{}); err != nil {
        t.Fatalf("workflow job not JSON-safe: %v", err)
    }
}

Try / catch

if err != nil {
    reportIssue("get_action_workflow_job", map[string]any{"job_id": id}, err, version())
    return err
}

Prevention

When it happens

Trigger: Calling get_action_workflow_job with a valid job ID after a dependency upgrade introduces serialization-unsafe fields; fork code attaching channels or funcs to the job struct.

Common situations: Not seen with stock releases; theoretical risk during go-github major upgrades.

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/64f0dc751c7764f9. Report an issue: GitHub.