Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool

JSON Error Messages Across Different Languages: A Comparison

When working with JSON data across different programming languages, understanding error messages can be a challenge. Each language implements JSON parsing differently, resulting in varied error messages that can range from cryptic to highly descriptive. This article compares JSON error reporting across popular programming languages to help you interpret these messages more effectively.

1. Common JSON Parsing Errors

Before diving into language specifics, let's identify the most common JSON parsing errors:

  • Mismatched brackets or braces
  • Missing or extra commas
  • Unquoted property names
  • Single quotes instead of double quotes
  • Trailing commas in arrays or objects
  • Invalid escape sequences
  • Non-string keys in objects
  • Invalid Unicode sequences
  • Data type mismatches
  • Unexpected end of input

2. Error Message Comparison

Let's examine how different languages report the same JSON errors. For our comparison, we'll use this intentionally problematic JSON:

Problematic JSON:

{
  "name": "Test Object",
  'description': "An object with errors",
  "count": 42,
  "items": [
    "item1",
    "item2",
    "item3",
  ],
  status: "active"
}

Issues: Single quotes around 'description', trailing comma after "item3", and unquoted property name status

3. JavaScript (Browser)

JavaScript's JSON parser provides concise but helpful error messages, focusing on position information:

Error for single quotes:

SyntaxError: Unexpected token ' in JSON at position 29

Error for trailing comma:

SyntaxError: Unexpected token ] in JSON at position 108

Error for unquoted property:

SyntaxError: Unexpected token s in JSON at position 116

Code example:

try {
  const data = JSON.parse(jsonString);
  console.log(data);
} catch (error) {
  console.error('JSON parsing failed:', error.message);
  
  // Extract position information
  const position = error.message.match(/position (d+)/);
  if (position && position[1]) {
    const pos = Number(position[1]);
    console.error(`Error near: ${jsonString.substring(Math.max(0, pos - 10), pos + 10)}`);
    console.error(`${' '.repeat(Math.min(10, pos))}^ Error around here`);
  }
}

JavaScript Error Characteristics

  • Strengths: Concise, includes position information, easily accessible in try/catch blocks
  • Weaknesses: No context about the expected structure, no line/column info in browsers
  • Best practice: Add your own context by showing the problematic section using the position value

4. Python

Python's json module provides error messages with line and column information, making it easier to locate problems:

Error for single quotes:

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: 
line 3 column 3 (char 29)

Error for trailing comma:

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: 
line 8 column 3 (char 108)

Code example:

import json

try:
    data = json.loads(json_string)
    print(data)
except json.JSONDecodeError as e:
    print(f"Error message: {str(e)}")
    print(f"Line: {e.lineno}, Column: {e.colno}, Position: {e.pos}")
    
    # Show the problematic line
    lines = json_string.splitlines()
    if 0 <= e.lineno-1 < len(lines):
        print("Problematic line:")
        print(lines[e.lineno-1])
        print(" " * (e.colno-1) + "^")

Python Error Characteristics

  • Strengths: Detailed error messages, line/column information, specific exception type
  • Weaknesses: Sometimes the error appears after the actual problem location
  • Best practice: Use the exception's lineno, colno, and pos attributes to pinpoint the error

5. Java

Java's JSON libraries like Jackson provide detailed error messages with path information:

Jackson error for single quotes:

com.fasterxml.jackson.core.JsonParseException: Unexpected character (''' (code 39)): 
expected double-quote to start field name
 at [Source: (String)"..."; line: 3, column: 4]

GSON error for the same issue:

com.google.gson.JsonSyntaxException: 
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 3 column 16 path $.

Code example (Jackson):

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

ObjectMapper mapper = new ObjectMapper();
try {
    Map<String, Object> data = mapper.readValue(jsonString, Map.class);
    System.out.println(data);
} catch (JsonProcessingException e) {
    System.err.println("JSON parsing error: " + e.getMessage());
    System.err.println("Location: Line " + e.getLocation().getLineNr() + 
                      ", Column " + e.getLocation().getColumnNr());
    
    // Extract problematic line
    String[] lines = jsonString.split("\n");
    if (e.getLocation().getLineNr() - 1 < lines.length) {
        String line = lines[e.getLocation().getLineNr() - 1];
        System.err.println("Problematic line: " + line);
        System.err.println(" ".repeat(e.getLocation().getColumnNr() - 1) + "^");
    }
}

Java Error Characteristics

  • Strengths: Very detailed error messages, stack traces, line/column information, path details
  • Weaknesses: Verbosity can be overwhelming, different libraries have different formats
  • Best practice: Extract the line/column information and use it to highlight the problematic section

6. C#/.NET

C#'s System.Text.Json provides moderately detailed error messages:

Error for single quotes:

System.Text.Json.JsonException: '''' is an invalid start of a property name. 
Expected a '"'. Path: $ | LineNumber: 2 | BytePositionInLine: 2.

Error for trailing comma:

System.Text.Json.JsonException: Expected end of array or comma delimiter. 
Path: $.items | LineNumber: 7 | BytePositionInLine: 2.

Code example:

using System;
using System.Text.Json;

try
{
    var data = JsonSerializer.Deserialize<dynamic>(jsonString);
    Console.WriteLine(data);
}
catch (JsonException ex)
{
    Console.WriteLine($"JSON parsing error: {ex.Message}");
    
    // Extract line and position from error message
    Console.WriteLine($"Path: {ex.Path}");
    Console.WriteLine($"Line Number: {ex.LineNumber}");
    Console.WriteLine($"Byte Position in Line: {ex.BytePositionInLine}");
    
    // Show problematic line
    string[] lines = jsonString.Split('
');
    if (ex.LineNumber > 0 && ex.LineNumber <= lines.Length)
    {
        string line = lines[ex.LineNumber - 1];
        Console.WriteLine($"Problematic line: {line}");
        Console.WriteLine($"{new string(' ', ex.BytePositionInLine)}^");
    }
}

C#/.NET Error Characteristics

  • Strengths: Structured exceptions with path, line, and position properties, clear explanation
  • Weaknesses: BytePositionInLine can be confusing for Unicode characters
  • Best practice: Use the JsonException properties to pinpoint and display the error location

7. PHP

PHP's json_decode() function doesn't provide detailed error messages by default, requiring extra steps for useful information:

Standard error information:

// json_decode() just returns null on error
// json_last_error() returns a code like JSON_ERROR_SYNTAX
// json_last_error_msg() returns a human-readable message

json_last_error(): 4
json_last_error_msg(): "Syntax error"

Code example with improved error reporting:

<?php
function jsonDecodeWithErrorInfo($json) {
    $result = json_decode($json);
    $error = json_last_error();
    
    if ($error !== JSON_ERROR_NONE) {
        $message = json_last_error_msg();
        
        // Find position by decoding chunks until error occurs
        $position = 0;
        for ($i = 0; $i <= strlen($json); $i++) {
            $chunk = substr($json, 0, $i);
            json_decode($chunk);
            if (json_last_error() !== JSON_ERROR_NONE) {
                $position = $i;
                break;
            }
        }
        
        // Calculate line and column
        $lines = explode("
", substr($json, 0, $position));
        $line = count($lines);
        $column = strlen(end($lines)) + 1;
        
        return [
            'error' => true,
            'message' => $message,
            'code' => $error,
            'position' => $position,
            'line' => $line,
            'column' => $column
        ];
    }
    
    return ['error' => false, 'data' => $result];
}

$result = jsonDecodeWithErrorInfo($jsonString);
if ($result['error']) {
    echo "JSON Error: {$result['message']}
";
    echo "Line: {$result['line']}, Column: {$result['column']}, Position: {$result['position']}
";
    
    // Display the problem line
    $lines = explode("
", $jsonString);
    if (isset($lines[$result['line'] - 1])) {
        echo "Problematic line: {$lines[$result['line'] - 1]}
";
        echo str_repeat(' ', $result['column'] - 1) . "^
";
    }
} else {
    var_dump($result['data']);
}
?>

PHP Error Characteristics

  • Strengths: Simple error system with standard error codes
  • Weaknesses: Very minimal error details, no position information by default
  • Best practice: Implement custom error detection as shown above to pinpoint the exact error location

8. Ruby

Ruby's JSON parser provides moderately helpful error messages:

Error for single quotes:

JSON::ParserError: 765: unexpected token at '{"name": "Test Object",
'description': "An object with errors",
...}'

Code example:

require 'json'

begin
  data = JSON.parse(json_string)
  puts data
rescue JSON::ParserError => e
  puts "JSON parsing error: #{e.message}"
  
  # Extract position information if available
  if e.message =~ /(d+): unexpected token/
    position = $1.to_i
    
    # Find line and column
    lines = json_string[0..position].split("
")
    line = lines.length
    column = lines.last.length
    
    puts "Error around position #{position}, Line #{line}, Column #{column}"
    
    # Show problematic line
    all_lines = json_string.split("
")
    if all_lines[line-1]
      puts "Problematic line: #{all_lines[line-1]}"
      puts "#{' ' * column}^"
    end
  end
end

Ruby Error Characteristics

  • Strengths: Specific exception type, includes position information
  • Weaknesses: Error message format is less structured, requiring regex to extract position
  • Best practice: Parse the error message to extract position and display context around the error

9. Go

Go's encoding/json package provides precise error messages:

Error for single quotes:

json: invalid character ''' looking for beginning of object key string

Error for trailing comma:

json: invalid character ']' looking for beginning of value

Code example:

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

func main() {
	var data map[string]interface{}
	err := json.Unmarshal([]byte(jsonString), &data)
	
	if err != nil {
		fmt.Printf("JSON parsing error: %s
", err)
		
		// For syntax errors, identify location
		if syntaxErr, ok := err.(*json.SyntaxError); ok {
			position := int(syntaxErr.Offset)
			fmt.Printf("Error at position: %d
", position)
			
			// Calculate line and column
			lines := strings.Split(jsonString[:position], "
")
			line := len(lines)
			column := len(lines[line-1]) + 1
			
			fmt.Printf("Line: %d, Column: %d
", line, column)
			
			// Show problematic line
			allLines := strings.Split(jsonString, "
")
			if line-1 < len(allLines) {
				fmt.Printf("Problematic line: %s
", allLines[line-1])
				fmt.Printf("%s^
", strings.Repeat(" ", column-1))
			}
		}
	} else {
		fmt.Printf("Parsed data: %v
", data)
	}
}

Go Error Characteristics

  • Strengths: Clean error messages, provides byte offset for syntax errors
  • Weaknesses: Only provides byte offset, requiring calculation for line/column
  • Best practice: Type assert to *json.SyntaxError to access the Offset field and display context

10. Unified Error Handling Strategy

Regardless of the language, a good error handling strategy should:

  1. Extract position information (line, column, and/or character position)
  2. Show the problematic line with a caret (^) marking the error location
  3. Provide context about what was expected vs. what was found
  4. Suggest possible fixes based on the error type
  5. Handle nested structures by showing the path to the error

Universal Error Display Function (JavaScript):

/**
 * Display JSON error in a universal format
 * @param {string} jsonString - The JSON string that failed to parse
 * @param {Error} error - The error thrown during parsing
 */
function displayJsonError(jsonString, error) {
  // Extract error information
  const errorInfo = {
    message: error.message,
    position: null,
    line: null,
    column: null
  };
  
  // Extract position from error message (different patterns)
  const posMatch = error.message.match(/position (d+)/);
  if (posMatch) {
    errorInfo.position = Number(posMatch[1]);
  }
  
  // If we have a position, calculate line and column
  if (errorInfo.position !== null) {
    const upToPosition = jsonString.substring(0, errorInfo.position);
    const lines = upToPosition.split('\n');
    errorInfo.line = lines.length;
    errorInfo.column = lines[lines.length - 1].length + 1;
  }
  
  // Display error summary
  console.error(`JSON Error: ${errorInfo.message}`);
  
  if (errorInfo.line !== null) {
    console.error(`Location: Line ${errorInfo.line}, Column ${errorInfo.column}`);
    
    // Show the problematic line with a marker
    const allLines = jsonString.split('\n');
    if (errorInfo.line <= allLines.length) {
      const problemLine = allLines[errorInfo.line - 1];
      console.error('Problematic line:');
      console.error(problemLine);
      console.error(`${' '.repeat(errorInfo.column - 1)}^`);
    }
    
    // Suggest fixes based on common patterns
    suggestJsonFix(errorInfo, jsonString);
  }
}

/**
 * Suggest possible fixes based on the error
 * @param {Object} errorInfo - Information about the error
 * @param {string} jsonString - The original JSON string
 */
function suggestJsonFix(errorInfo, jsonString) {
  const message = errorInfo.message.toLowerCase();
  
  if (message.includes("unexpected token '")) {
    console.error("Suggestion: Check for single quotes, which should be double quotes in JSON.");
  } else if (message.includes('unexpected token }') || message.includes('unexpected token ]')) {
    console.error("Suggestion: Check for missing commas or extra commas before this closing bracket.");
  } else if (message.includes('unexpected end of input')) {
    console.error("Suggestion: JSON is incomplete. Check for missing closing brackets or quotes.");
  } else if (message.includes('unexpected token :')) {
    console.error("Suggestion: Property names should be enclosed in double quotes.");
  }
}

11. Best Practices for Cross-Language JSON Usage

When working with JSON across multiple languages:

  • Use validators before attempting to parse in production code
  • Create unified error handlers for each language that standardize the output format
  • Include the original JSON (or a condensed version) in error logs for debugging
  • Consider schema validation to catch more semantic errors beyond syntax issues
  • Implement proper logging that includes the error context, not just the message

12. Language-Specific JSON Validation Libraries

Many languages offer specialized JSON validation libraries with superior error reporting:

JavaScript:

  • jsonlint - Detailed error messages with line/column
  • ajv - Advanced schema validation with descriptive errors
  • json-schema-validator - Path-based error reporting

Python:

  • jsonschema - Advanced schema validation
  • json-validator - Visual error indicators
  • pydantic - Combines parsing with validation

Java:

  • Everit JSON Schema - Detailed validation errors
  • json-schema-validator - Path-based reporting
  • jsonassert - Specialized for testing JSON equality

Go:

  • gojsonschema - Schema validation with detailed errors
  • validator - General validation including JSON
  • go-playground/validator - Struct validation

Pro Tip

When developing APIs consumed by multiple language clients, include a "debug" mode that returns more verbose JSON error messages. This helps clients identify issues more quickly regardless of their language's native error reporting capabilities.

13. Conclusion

Understanding JSON error messages across different programming languages allows you to debug more efficiently in polyglot environments. While each language has its own error reporting style, the fundamental JSON specification remains the same. By leveraging language-specific error details and applying consistent error handling strategies, you can quickly pinpoint and resolve JSON parsing issues regardless of your technology stack.

Remember that good error messages are not just about reporting failures—they should guide users toward solutions. Investing time in better error handling pays dividends in reduced debugging time and improved developer experience.

Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool