github/github-mcp-server · error
failed to unmarshal JSON text: %w
Error message
failed to unmarshal JSON text: %w
What it means
jsonTextToCSV failed to decode the tool's JSON output text before converting it to CSV. json.Decoder.Decode returns errors like SyntaxError (malformed JSON), UnexpectedEOF (truncated text), or invalid UTF-8 errors when the input is not a complete, single JSON document. This means the upstream tool produced non-JSON text — typically an error message, plain-text output, or a truncated payload — while the server was configured with CSV output format.
Source
Thrown at pkg/github/csv_output.go:114
}
csvText, err := jsonTextToCSV(text.Text)
if err != nil {
return utils.NewToolResultErrorFromErr("failed to convert response to CSV", err)
}
result.Content = []mcp.Content{&mcp.TextContent{Text: csvText}}
result.StructuredContent = nil
return result
}
func jsonTextToCSV(text string) (string, error) {
decoder := json.NewDecoder(strings.NewReader(text))
decoder.UseNumber()
var value any
if err := decoder.Decode(&value); err != nil {
return "", fmt.Errorf("failed to unmarshal JSON text: %w", err)
}
doc := csvDocument(value)
if len(doc.metadata) == 0 && len(doc.rows) == 0 {
return "", nil
}
var buf bytes.Buffer
writeCSVMetadata(&buf, doc.metadata)
if len(doc.rows) == 0 {
return buf.String(), nil
}
headers := csvHeaders(doc.rows)
if len(headers) == 0 {
return buf.String(), nil
}
View on GitHub (pinned to 0ea1f775a7)
Solutions
- Re-run the tool without the CSV output format to see the raw payload and confirm it is JSON
- Choose CSV output only for tabular tools (list_* tools returning arrays of objects)
- If the payload looks like JSON but still fails, check for truncation (content window limits) or BOM/whitespace prefix
- Report tools that emit non-JSON text so they can be made CSV-safe upstream
Example fix
// before
var value any
if err := decoder.Decode(&value); err != nil {
return "", fmt.Errorf("failed to unmarshal JSON text: %w", err)
}
// after — reject non-JSON early with a payload preview
if !json.Valid([]byte(text)) {
return "", fmt.Errorf("tool output is not valid JSON (csv conversion aborted): %.120s", text)
} Defensive patterns
Strategy: validation
Validate before calling
// before requesting CSV conversion, verify the text is a JSON document
func isConvertibleJSON(text string) bool {
trimmed := strings.TrimSpace(text)
return strings.HasPrefix(trimmed, "{") || strings.HasPrefix(trimmed, "[")
} Type guard
func isJSONText(s string) bool { return json.Valid([]byte(s)) } Try / catch
if err := decoder.Decode(&value); err != nil {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
// not JSON at all: return the raw text instead of failing the whole tool call
return text, nil
}
return "", fmt.Errorf("failed to unmarshal JSON text: %w", err)
} Prevention
- Only request CSV output for tools that emit JSON arrays/objects (list_* tools)
- Keep tool outputs valid JSON even on partial failures so format conversion stays possible
- Watch for truncated payloads when content-window limits are in play — re-fetch with pagination instead of converting
When it happens
Trigger: Running any tool with output format csv where the tool's textual result is not valid JSON: tools that return plain strings (URLs, plain text), error strings placed in TextContent, or responses truncated by size limits.
Common situations: MCP client requests output format csv for a tool whose content is inherently non-JSON; version changes that made a tool emit human-readable text; empty TextContent from a failed upstream call.
Related errors
- failed to write CSV header: %w
- failed to write CSV row: %w
- failed to flush CSV: %w
- GitHub App authentication and GITHUB_PERSONAL_ACCESS_TOKEN a
- GitHub App ID or client ID is required (GITHUB_APP_ID)
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/e281faa69b962977.
Report an issue: GitHub.