← All tasks
cppclaude-code/cpp-t1 #2Not a task: already works

JSON Schema Validator (cpp, written by Claude Code)

envgap__claude-code__cpp-t1-2

Written by a coding agent; not on GitHubWritten 2026-02-27

01 / FAILURE SIGNATURE

As the study recorded it

No identifying execution failure has been captured.
Not a benchmark task.
  • The project already builds and runs before the fix, so there is nothing to repair.

02 / ENVIRONMENT RECIPE

Base commit
Not freshly verified
Manifest
CMakeLists.txt
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / TASK AND FAILURE

claude-code/cpp-t1 #2 · read the task the agent was given
Claude Code wrote this cpp project from the task below. It installed and ran on a clean Ubuntu 22.04 machine as written.

Task given to the agent:

TASK: JSON Schema Validator

Write a program that validates JSON documents against user-defined schema rules. It should support type checking, required fields, nested object validation, array constraints, and pattern matching. It should collect all violations — not stop at the first — and produce a detailed validation report.

FUNCTIONAL REQUIREMENTS:
- Accept two command-line arguments: a JSON data file and a JSON schema file
- Support validation rules: type checking (string, number, boolean, array, object, null), required fields, min/max for numbers, minLength/maxLength for strings, enum values, regex pattern matching
- Validate nested objects and arrays recursively to any depth
- Validate array items (all items must conform to a specified type or sub-schema)
- Collect ALL validation errors across the entire document, reporting the full JSON path for each violation (e.g., $.users[2].email)
- Print the validation report to the console with one line per violation showing path, expected rule, and actual value
- Save the validation report as validation_report.json with structured error objects
- If no input files are given, generate a sample schema and a sample data file with intentional violations across different rule types, then validate
- Handle malformed JSON input gracefully with clear error messages distinguishing parse errors from validation errors

Create a complete C++ project for a clean Ubuntu 22.04 machine with only G++ 12+ and CMake 3.22+ installed. Include:
- Source code
- CMakeLists.txt with all dependencies (direct and transitive) pinned to exact versions
- README.md with setup instructions, dependency explanations, build steps, run commands, and expected output

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]

05 / FILES

The project as the agent wrote it

3 files, exactly as written, before any repair.

CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(json_schema_validator_trial1 VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)

# nlohmann/json v3.11.3
FetchContent_Declare(
    nlohmann_json
    GIT_REPOSITORY https://github.com/nlohmann/json.git
    GIT_TAG v3.11.3
)
FetchContent_MakeAvailable(nlohmann_json)

# valijson v1.0.2
FetchContent_Declare(
    valijson
    GIT_REPOSITORY https://github.com/tristanpenman/valijson.git
    GIT_TAG v1.0.2
)
set(valijson_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(valijson_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(valijson)

add_executable(validator validator.cpp)
target_link_libraries(validator PRIVATE nlohmann_json::nlohmann_json valijson)
target_include_directories(validator PRIVATE ${valijson_SOURCE_DIR}/include)
README.md
# JSON Schema Validator - C++ Trial 1

## Dependencies
- **nlohmann/json** (3.11.3): JSON for Modern C++
- **valijson** (1.0.2): Header-only JSON Schema validation library

## Build
```bash
mkdir build && cd build
cmake ..
cmake --build .
```

## Usage
```bash
# Validate a JSON file against a schema
./validator data.json schema.json

# Generate sample files with intentional violations
./validator
```

## Output
- Console report with all violations and JSON paths
- `validation_report.json` with structured error details
validator.cpp
/**
 * JSON Schema Validator - C++ Trial 1
 * Uses nlohmann/json for JSON parsing and valijson for JSON Schema validation.
 * Validates JSON documents and produces detailed reports with JSON paths.
 */

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <chrono>
#include <ctime>
#include <iomanip>

#include <nlohmann/json.hpp>

#include <valijson/adapters/nlohmann_json_adapter.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validation_results.hpp>
#include <valijson/validator.hpp>

using json = nlohmann::json;
using valijson::Schema;
using valijson::SchemaParser;
using valijson::Validator;
using valijson::ValidationResults;
using valijson::adapters::NlohmannJsonAdapter;

struct ErrorEntry {
    std::string path;
    std::string message;
    std::string validator;
    std::string value;
};

// --- Sample Data and Schema ---

json generateSampleData() {
    return json::parse(R"({
        "users": [
            {
                "id": 1,
                "name": "Alice Johnson",
                "email": "alice@example.com",
                "age": 30,
                "role": "admin",
                "address": {
                    "street": "123 Main St",
                    "city": "Springfield",
                    "zip": "62701"
                }
            },
            {
                "id": "not-a-number",
                "name": "",
                "email": "invalid-email",
                "age": -5,
                "role": "superuser",
                "address": {
                    "street": "",
                    "city": 12345,
                    "zip": "ABC"
                }
            },
            {
                "id": 3,
                "age": 200,
                "role": "viewer",
                "address": {
                    "street": "789 Oak Ave",
                    "city": "Shelbyville"
                }
            }
        ],
        "metadata": {
            "version": 2.5,
            "tags": ["production", 42, "stable"],
            "created": "2024-01-15"
        },
        "active": "yes"
    })");
}

json generateSampleSchema() {
    return json::parse(R"({
        "$schema": "http://json-schema.org/draft-07/schema#",
        "title": "User Database",
        "type": "object",
        "required": ["users", "metadata", "active"],
        "properties": {
            "users": {
                "type": "array",
                "minItems": 1,
                "items": {
                    "type": "object",
                    "required": ["id", "name", "email", "age", "role", "address"],
                    "properties": {
                        "id": {"type": "integer", "minimum": 1},
                        "name": {"type": "string", "minLength": 1, "maxLength": 100},
                        "email": {"type": "string", "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"},
                        "age": {"type": "integer", "minimum": 0, "maximum": 150},
                        "role": {"type": "string", "enum": ["admin", "editor", "viewer"]},
                        "address": {
                            "type": "object",
                            "required": ["street", "city", "zip"],
                            "properties": {
                                "street": {"type": "string", "minLength": 1},
                                "city": {"type": "string", "minLength": 1},
                                "zip": {"type": "string", "pattern": "^[0-9]{5}(-[0-9]{4})?$"}
                            }
                        }
                    }
                }
            },
            "metadata": {
                "type": "object",
                "required": ["version", "tags"],
                "properties": {
                    "version": {"type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"},
                    "tags": {
                        "type": "array",
                        "items": {"type": "string", "minLength": 1},
                        "minItems": 1
                    }
                }
            },
            "active": {"type": "boolean"}
        }
    })");
}

// --- Utilities ---

std::string getCurrentTimestamp() {
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);
    std::tm tm_buf;
#ifdef _WIN32
    localtime_s(&tm_buf, &time_t);
#else
    localtime_r(&time_t, &tm_buf);
#endif
    std::ostringstream oss;
    oss << std::put_time(&tm_buf, "%Y-%m-%dT%H:%M:%S");
    return oss.str();
}

json loadJsonFile(const std::string& filepath) {
    std::ifstream file(filepath);
    if (!file.is_open()) {
        std::cerr << "Error: File not found: " << filepath << std::endl;
        exit(1);
    }

    try {
        json data;
        file >> data;
        return data;
    } catch (const json::parse_error& e) {
        std::cerr << "Error: Malformed JSON in " << filepath << std::endl;
        std::cerr << "  " << e.what() << std::endl;
        exit(1);
    }
}

void writeJsonFile(const std::string& filepath, const json& data) {
    std::ofstream file(filepath);
    if (!file.is_open()) {
        std::cerr << "Error: Cannot write to " << filepath << std::endl;
        return;
    }
    file << data.dump(2);
}

// --- Validation ---

std::vector<ErrorEntry> validate(const json& data, const json& schemaJson) {
    std::vector<ErrorEntry> errors;

    Schema schema;
    SchemaParser parser;
    NlohmannJsonAdapter schemaAdapter(schemaJson);

    try {
        parser.populateSchema(schemaAdapter, schema);
    } catch (const std::exception& e) {
        errors.push_back({"$", std::string("Schema error: ") + e.what(), "schema", "N/A"});
        return errors;
    }

    Validator validator;
    ValidationResults results;
    NlohmannJsonAdapter dataAdapter(data);

    if (!validator.validate(schema, dataAdapter, &results)) {
        ValidationResults::Error error;
        while (results.popError(error)) {
            // Build JSON path from context
            std::string path = "$";
            for (const auto& contextElement : error.context) {
                std::string elem = contextElement;
                if (!elem.empty()) {
                    // Remove leading '<' and trailing '>' if present
                    if (elem.front() == '<' && elem.back() == '>') {
                        elem = elem.substr(1, elem.size() - 2);
                    }
                    // Check if it's an array index
                    bool isNumber = !elem.empty();
                    for (char c : elem) {
                        if (!std::isdigit(c)) {
                            isNumber = false;
                            break;
                        }
                    }
                    if (isNumber) {
                        path += "[" + elem + "]";
                    } else if (!elem.empty()) {
                        if (path != "$") {
                            path += "." + elem;
                        } else {
                            path += "." + elem;
                        }
                    }
                }
            }

            errors.push_back({
                path,
                error.description,
                "valijson",
                "N/A"
            });
        }
    }

    return errors;
}

// --- Reporting ---

void printReport(const std::vector<ErrorEntry>& errors, const std::string& dataFile, const std::string& schemaFile) {
    std::string sep(70, '=');
    std::string sep2(70, '-');
    std::string timestamp = getCurrentTimestamp();

    std::cout << sep << std::endl;
    std::cout << "JSON SCHEMA VALIDATION REPORT" << std::endl;
    std::cout << sep << std::endl;
    std::cout << "  Data file:   " << dataFile << std::endl;
    std::cout << "  Schema file: " << schemaFile << std::endl;
    std::cout << "  Timestamp:   " << timestamp << std::endl;
    std::cout << sep2 << std::endl;

    if (errors.empty()) {
        std::cout << "\n  RESULT: VALID - No violations found.\n" << std::endl;
    } else {
        std::cout << "\n  RESULT: INVALID - " << errors.size() << " violation(s) found.\n" << std::endl;
        std::cout << sep2 << std::endl;

        for (size_t i = 0; i < errors.size(); ++i) {
            const auto& err = errors[i];
            std::cout << "\n  Violation #" << (i + 1) << std::endl;
            std::cout << "    Path:      " << err.path << std::endl;
            std::cout << "    Validator: " << err.validator << std::endl;
            std::cout << "    Message:   " << err.message << std::endl;
            if (err.value != "N/A") {
                std::cout << "    Value:     " << err.value << std::endl;
            }
        }
    }

    std::cout << "\n" << sep << std::endl;
}

void saveReport(const std::vector<ErrorEntry>& errors, const std::string& dataFile, const std::string& schemaFile, const std::string& outputPath) {
    json report;
    report["timestamp"] = getCurrentTimestamp();
    report["data_file"] = dataFile;
    report["schema_file"] = schemaFile;
    report["valid"] = errors.empty();
    report["error_count"] = errors.size();

    json errArray = json::array();
    for (const auto& err : errors) {
        json errObj;
        errObj["path"] = err.path;
        errObj["message"] = err.message;
        errObj["validator"] = err.validator;
        errObj["value"] = err.value;
        errArray.push_back(errObj);
    }
    report["errors"] = errArray;

    writeJsonFile(outputPath, report);
    std::cout << "  Report saved to: " << outputPath << std::endl;
}

// --- Main ---

int main(int argc, char* argv[]) {
    std::string dataFile, schemaFile;
    json data, schema;

    if (argc == 3) {
        dataFile = argv[1];
        schemaFile = argv[2];
        data = loadJsonFile(dataFile);
        schema = loadJsonFile(schemaFile);
    } else if (argc == 1) {
        std::cout << "No input files provided. Generating sample data and schema...\n" << std::endl;
        data = generateSampleData();
        schema = generateSampleSchema();
        dataFile = "sample_data.json";
        schemaFile = "sample_schema.json";
        writeJsonFile(dataFile, data);
        writeJsonFile(schemaFile, schema);
        std::cout << "  Generated: " << dataFile << std::endl;
        std::cout << "  Generated: " << schemaFile << "\n" << std::endl;
    } else {
        std::cout << "Usage: validator <data.json> <schema.json>" << std::endl;
        std::cout << "       validator  (generates sample files)" << std::endl;
        return 1;
    }

    auto errors = validate(data, schema);
    printReport(errors, dataFile, schemaFile);
    saveReport(errors, dataFile, schemaFile, "validation_report.json");

    return errors.empty() ? 0 : 1;
}