| name | claude-code-schema-validation |
| description | Guide and workflow for Claude Code Schema Validation & Testing. Use when you need Claude Code Schema Validation & Testing. |
Claude Code Schema Validation & Testing
Purpose: Comprehensive guide for validating Claude Code settings.json and agent files using official and community tools.
🎯 Official JSON Schema Support (RESOLVED - Sept 2025)
As of September 29, 2025, Anthropic provides official JSON Schema validation for Claude Code settings.
Official Schema URL
https://json.schemastore.org/claude-code-settings.json
Source: GitHub Issue #2783 - Closed as completed
✅ Using Official Schema Validation
Step 1: Add Schema Reference to settings.json
Add the $schema field at the top of your settings.json:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"BASH_MAX_OUTPUT_LENGTH": "5000"
},
"permissions": {
"allow": ["Bash(git:*)"]
},
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [...]
}
]
}
}
Step 2: Enable IDE Validation
Once the $schema field is added, your IDE will automatically:
- ✅ Validate settings structure
- ✅ Show errors for invalid fields
- ✅ Provide autocomplete for available options
- ✅ Display documentation on hover
Supported IDEs:
- VS Code
- IntelliJ IDEA
- WebStorm
- Any editor with JSON Schema support
🧪 Unit Testing Framework
Option 1: Official Schema Validation (Recommended)
Use the official schema with standard JSON validation tools:
Using Python (jsonschema):
"""Test Claude Code settings.json validation"""
import json
import requests
from jsonschema import validate, ValidationError
def test_settings_validation():
"""Validate settings.json against official schema"""
schema_url = "https://json.schemastore.org/claude-code-settings.json"
schema = requests.get(schema_url).json()
with open('.claude/settings.json', 'r') as f:
settings = json.load(f)
try:
validate(instance=settings, schema=schema)
print("✅ settings.json is valid")
return True
except ValidationError as e:
print(f"❌ Validation error: {e.message}")
print(f" Path: {' -> '.join(str(p) for p in e.path)}")
return False
if __name__ == "__main__":
success = test_settings_validation()
exit(0 if success else 1)
Using Node.js (ajv):
#!/usr/bin/env node
const Ajv = require('ajv');
const fs = require('fs');
const https = require('https');
async function testSettingsValidation() {
const schemaUrl = 'https://json.schemastore.org/claude-code-settings.json';
const schema = await new Promise((resolve, reject) => {
https.get(schemaUrl, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => resolve(JSON.parse(data)));
}).on('error', reject);
});
const settings = JSON.parse(fs.readFileSync('.claude/settings.json', 'utf8'));
const ajv = new ();
valid = ajv.(schema, settings);
(valid) {
.();
;
} {
.();
ajv..( {
.();
});
;
}
}
().( process.(success ? : ));
Option 2: Community Tools
A. claude-code-settings-schema (npm)
Generates local schema file for offline validation:
npx claude-code-settings-schema
{
"$schema": "./claude-code-settings.schema.json",
...
}
Benefits:
- Offline validation
- IDE autocomplete and IntelliSense
- Based on official Anthropic documentation
B. claude-json-validator (Python CLI)
Standalone validator for settings files:
git clone https://github.com/trial123Zel/claude-json-validator
cd claude-json-validator
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python claude-json-validator.py ~/.claude/settings.json
python claude-json-validator.py .claude/settings.json --verbose
python claude-json-validator.py settings.json --strict
Exit Codes:
0: Valid (warnings allowed unless --strict)
1: Errors found
🔧 Pre-Commit Hook Integration
Method 1: Using Official Schema (Python)
File: .claude/hooks/validate_settings.py
"""Pre-commit hook to validate settings.json"""
import json
import sys
from pathlib import Path
try:
import requests
from jsonschema import validate, ValidationError
except ImportError:
print("⚠️ jsonschema not installed, skipping validation")
print(" Install with: pip install jsonschema requests")
sys.exit(0)
def validate_settings():
"""Validate all settings.json files in the project"""
schema_url = "https://json.schemastore.org/claude-code-settings.json"
settings_files = [
Path.home() / '.claude' / 'settings.json',
Path('.claude') / 'settings.json',
]
errors = []
for settings_file in settings_files:
if not settings_file.exists():
continue
print(f"🔍 Validating {settings_file}...")
try:
schema = requests.get(schema_url, timeout=5).json()
with open(settings_file, 'r') as f:
settings = json.load(f)
validate(instance=settings, schema=schema)
()
ValidationError e:
()
()
errors.append((settings_file, e))
json.JSONDecodeError e:
()
errors.append((settings_file, e))
Exception e:
()
errors:
()
()
__name__ == :
success = validate_settings()
sys.exit( success )
Register in .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "bash -c 'if [[ \"$CLAUDE_TOOL_INPUT\" == *\"settings.json\"* ]]; then python3 .claude/hooks/validate_settings.py; fi'",
"description": "Validate settings.json before writing"
}
]
}
]
}
}
Method 2: Using /doctor Command
The simplest validation method:
/doctor
Advantages:
- Built into Claude Code
- No external dependencies
- Validates settings, agents, hooks
- Fast and reliable
Pre-commit hook:
#!/bin/bash
echo "🔍 Running Claude Code validation..."
if command -v claude >/dev/null 2>&1; then
claude /doctor --quiet || {
echo "❌ /doctor validation failed"
exit 1
}
echo "✅ /doctor validation passed"
else
echo "⚠️ claude CLI not found, skipping /doctor validation"
fi
exit 0
🧪 Agent Frontmatter Validation
Validation Script for Agent Files
File: .claude/hooks/validate_agents.py
"""Validate Claude Code agent frontmatter"""
import re
import sys
from pathlib import Path
def validate_agent_frontmatter(agent_file):
"""Validate agent file frontmatter"""
with open(agent_file, 'r') as f:
content = f.read()
if not content.startswith('---\n'):
return False, "Missing frontmatter opening '---'"
match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if not match:
return False, "Invalid frontmatter structure"
frontmatter = match.group(1)
required_fields = ['name', 'description']
missing_fields = []
for field in required_fields:
pattern = f'^{field}:\\s*.+$'
if not re.search(pattern, frontmatter, re.MULTILINE):
missing_fields.append(field)
if missing_fields:
return False, f"Missing required fields: {.join(missing_fields)}"
quoted_pattern =
re.search(quoted_pattern, frontmatter, re.MULTILINE):
,
,
():
agent_dirs = [
Path() / ,
Path.home() / / ,
]
errors = []
agent_dir agent_dirs:
agent_dir.exists():
agent_file agent_dir.glob():
()
valid, message = validate_agent_frontmatter(agent_file)
valid:
()
:
()
errors.append((agent_file, message))
errors:
()
()
__name__ == :
success = validate_all_agents()
sys.exit( success )
🚀 CI/CD Integration
GitHub Actions Workflow
File: .github/workflows/validate-claude-config.yml
name: Validate Claude Code Configuration
on:
pull_request:
paths:
- '.claude/**'
push:
branches: [main]
paths:
- '.claude/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install jsonschema requests pyyaml
- name: Validate settings.json
run: |
python3 .claude/hooks/validate_settings.py
- name: Validate agent frontmatter
run: |
python3 .claude/hooks/validate_agents.py
-
Pre-commit Framework Integration
File: .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: validate-claude-settings
name: Validate Claude Code settings
entry: python3 .claude/hooks/validate_settings.py
language: system
pass_filenames: false
files: '\.claude/settings\.json$'
- id: validate-claude-agents
name: Validate Claude Code agents
entry: python3 .claude/hooks/validate_agents.py
language: system
pass_filenames: false
files: '\.claude/agents/.*\.md$'
- id: check-claude-json
name: Check Claude Code JSON syntax
entry: python3 -m json.tool
language: system
📊 Complete Test Suite Example
File: tests/test_claude_config.py
"""Complete test suite for Claude Code configuration"""
import json
import unittest
from pathlib import Path
import requests
from jsonschema import validate, ValidationError
class TestClaudeCodeConfig(unittest.TestCase):
"""Test Claude Code configuration files"""
@classmethod
def setUpClass(cls):
"""Load schema once for all tests"""
schema_url = "https://json.schemastore.org/claude-code-settings.json"
cls.schema = requests.get(schema_url).json()
def test_project_settings_valid(self):
"""Test project settings.json is valid"""
settings_file = Path('.claude/settings.json')
self.assertTrue(settings_file.exists(), "settings.json not found")
with open(settings_file, 'r') as f:
settings = json.load(f)
validate(instance=settings, schema=self.schema)
def test_settings_has_schema_reference(self):
"""Test settings.json includes $schema field"""
with open('.claude/settings.json', 'r') as f:
settings = json.load(f)
self.assertIn(, settings, )
.assertIn(, settings[])
():
(, ) f:
settings = json.load(f)
settings:
hook_type, hooks_list settings[].items():
i, hook_entry (hooks_list):
hook_entry:
.assertIsInstance(
hook_entry[],
,
)
():
agents_dir = Path()
agents_dir.exists():
.skipTest()
agent_file agents_dir.glob():
.subTest(agent=agent_file.name):
(agent_file, ) f:
content = f.read()
.assertTrue(
content.startswith(),
)
re
= re.(, content, re.DOTALL)
.assertIsNotNone(, )
frontmatter = .group()
.assertRegex(
frontmatter,
,
,
flags=re.MULTILINE
)
.assertRegex(
frontmatter,
,
,
flags=re.MULTILINE
)
.assertNotRegex(
frontmatter,
,
,
flags=re.MULTILINE
)
__name__ == :
unittest.main()
Run tests:
python3 tests/test_claude_config.py
python3 tests/test_claude_config.py TestClaudeCodeConfig.test_hooks_use_string_matchers
python3 tests/test_claude_config.py -v
🎯 Best Practices
1. Always Use Official Schema
Add $schema field to all settings.json files:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
...
}
2. Enable IDE Validation
Configure your IDE to use JSON Schema validation:
- VS Code: Automatic with
$schema field
- IntelliJ: Enable JSON Schema support
- Vim/Neovim: Use CoC with json plugin
3. Run /doctor Regularly
/doctor
claude /doctor --quiet
4. Validate in Pre-commit Hooks
Add validation to prevent invalid configs:
#!/bin/bash
python3 .claude/hooks/validate_settings.py || exit 1
python3 .claude/hooks/validate_agents.py || exit 1
5. Test in CI/CD
Add validation to your CI pipeline:
- name: Validate Claude Config
run: |
python3 tests/test_claude_config.py
🔍 Troubleshooting
Schema Validation Fails
Problem: jsonschema validation errors
Solution:
- Check official schema is accessible:
curl https://json.schemastore.org/claude-code-settings.json
- Verify JSON syntax:
python3 -m json.tool settings.json
- Run
/doctor for official validation
- Check schema version matches Claude Code version
IDE Not Showing Validation
Problem: No autocomplete or error highlighting
Solution:
- Ensure
$schema field is present
- Reload IDE window/restart
- Check JSON Schema plugin is installed
- Verify settings.json is recognized as JSON file
Agent Frontmatter Errors
Problem: Agent parse errors in /doctor
Solution:
- Run validation script:
python3 .claude/hooks/validate_agents.py
- Check frontmatter uses unquoted values
- Verify both
name and description fields present
- Ensure frontmatter structure:
---\nfields\n---
📚 Additional Resources
Last Updated: 2025-11-17
Schema Version: As of September 29, 2025
Applies To: Claude Code 2.0+