validating-json-data
Validates JSON data against JSON Schema using the z-schema library. Use when the user needs to validate JSON, check data against a schema, handle validation errors, use custom format validators, work with JSON Schema drafts 04 through 2020-12, set up z-schema in a project, compile schemas with cross-references, resolve remote $ref, configure validation options, or inspect error details. Covers sync/async modes, safe error handling, schema pre-compilation, remote references, TypeScript types, and browser/UMD usage.
How do I install this agent skill?
npx skills add https://github.com/zaggino/z-schema --skill validating-json-dataIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill provides instructions for JSON validation using z-schema. It correctly identifies the risk of indirect prompt injection when handling untrusted data and includes a documentation example for schema loading that demonstrates potential path traversal if not implemented with proper input validation.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
- Runlayerpass
4 files scanned · No issues
What does this agent skill do?
Validating JSON Data with z-schema
z-schema validates JSON data against JSON Schema (draft-04, draft-06, draft-07, draft-2019-09, draft-2020-12). Default draft: draft-2020-12.
Quick start
import ZSchema from 'z-schema';
const validator = ZSchema.create();
const schema = {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'integer', minimum: 0 },
},
required: ['name'],
};
// Throws on invalid data
validator.validate({ name: 'Alice', age: 30 }, schema);
Install: npm install z-schema
Choosing a validation mode
z-schema has four modes based on two toggles: async and safe. Pick the one that fits the use case.
| Mode | Factory call | Returns | Use when |
|---|---|---|---|
| Sync throw | ZSchema.create() | true or throws ValidateError | Default — simple scripts and middleware |
| Sync safe | ZSchema.create({ safe: true }) | { valid, err? } | Need to inspect errors without try/catch |
| Async throw | ZSchema.create({ async: true }) | Promise<true> or rejects | Using async format validators |
| Async safe | ZSchema.create({ async: true, safe: true }) | Promise<{ valid, err? }> | Async + non-throwing |
Sync throw (default)
import ZSchema from 'z-schema';
const validator = ZSchema.create();
try {
validator.validate(data, schema);
} catch (err) {
// err is ValidateError
console.log(err.details); // SchemaErrorDetail[]
}
Sync safe
const validator = ZSchema.create({ safe: true });
const result = validator.validate(data, schema);
if (!result.valid) {
console.log(result.err?.details);
}
Or call .validateSafe() on a regular (throwing) validator for the same result shape:
const validator = ZSchema.create();
const { valid, err } = validator.validateSafe(data, schema);
Async throw
Required when using async format validators.
const validator = ZSchema.create({ async: true });
try {
await validator.validate(data, schema);
} catch (err) {
console.log(err.details);
}
Async safe
const validator = ZSchema.create({ async: true, safe: true });
const { valid, err } = await validator.validate(data, schema);
Inspecting errors
ValidateError has .details — an array of SchemaErrorDetail:
interface SchemaErrorDetail {
message: string; // "Expected type string but found type number"
code: string; // "INVALID_TYPE"
params: (string | number | Array<string | number>)[];
path: string | Array<string | number>; // "#/age" or ["age"]
keyword?: string; // "type", "required", "minLength", etc.
inner?: SchemaErrorDetail[]; // sub-errors from anyOf/oneOf/not
schemaPath?: Array<string | number>;
schemaId?: string;
}
Example: walking nested errors
Combinators (anyOf, oneOf, not) produce nested inner errors:
const { valid, err } = validator.validateSafe(data, schema);
if (!valid && err) {
for (const detail of err.details) {
console.log(`${detail.path}: [${detail.code}] ${detail.message}`);
if (detail.inner) {
for (const sub of detail.inner) {
console.log(` └─ ${sub.path}: [${sub.code}] ${sub.message}`);
}
}
}
}
Filtering errors
Pass ValidateOptions as the third argument to include or exclude specific error codes:
// Only report type errors
validator.validate(data, schema, { includeErrors: ['INVALID_TYPE'] });
// Suppress string-length errors
validator.validate(data, schema, { excludeErrors: ['MIN_LENGTH', 'MAX_LENGTH'] });
For the full error code list, see references/error-codes.md.
Schema pre-compilation
Compile schemas at startup for better runtime performance and to resolve cross-references:
const validator = ZSchema.create();
const schemas = [
{
id: 'address',
type: 'object',
properties: { city: { type: 'string' }, zip: { type: 'string' } },
required: ['city'],
},
{
id: 'person',
type: 'object',
properties: {
name: { type: 'string' },
home: { $ref: 'address' },
},
required: ['name'],
},
];
// Compile all schemas (validates them and registers references)
validator.validateSchema(schemas);
// Validate data using a compiled schema ID
validator.validate({ name: 'Alice', home: { city: 'Paris' } }, 'person');
Remote references
Manual registration
ZSchema.setRemoteReference('http://example.com/schemas/address.json', addressSchema);
// or per-instance:
validator.setRemoteReference('http://example.com/schemas/person.json', personSchema);
Automatic loading via schema reader
import fs from 'node:fs';
import path from 'node:path';
ZSchema.setSchemaReader((uri) => {
const filePath = path.resolve(__dirname, 'schemas', uri + '.json');
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
});
Diagnosing missing references
const { valid, err } = validator.validateSafe(data, schema);
if (!valid && err) {
const missing = validator.getMissingReferences(err);
const remote = validator.getMissingRemoteReferences(err);
}
Custom format validators
Global (shared across all validator instances)
ZSchema.registerFormat('postal-code', (value) => {
return typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value);
});
Instance-scoped
const validator = ZSchema.create();
validator.registerFormat('postal-code', (value) => {
return typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value);
});
Via options at creation time
const validator = ZSchema.create({
customFormats: {
'postal-code': (value) => typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value),
},
});
Async format validators
Return Promise<boolean>. Requires { async: true }.
const validator = ZSchema.create({ async: true });
validator.registerFormat('user-exists', async (value) => {
if (typeof value !== 'number') return false;
const user = await db.findUser(value);
return user != null;
});
Listing registered formats
const formats = ZSchema.getRegisteredFormats();
Choosing a draft version
Set the draft explicitly if the schema targets a specific version:
const validator = ZSchema.create({ version: 'draft-07' });
Valid values: 'draft-04', 'draft-06', 'draft-07', 'draft2019-09', 'draft2020-12' (default), 'none'.
For a feature comparison across drafts, see references/draft-comparison.md.
Common options
| Option | Default | Purpose |
|---|---|---|
breakOnFirstError | false | Stop validation at the first error |
noEmptyStrings | false | Reject empty strings as type string |
noEmptyArrays | false | Reject empty arrays as type array |
strictMode | false | Enable all strict checks at once |
ignoreUnknownFormats | false | Suppress unknown format errors (modern drafts always ignore) |
formatAssertions | null | null=always assert, true=respect vocabulary, false=annotation-only |
reportPathAsArray | false | Report error paths as arrays instead of JSON Pointer strings |
For the full options reference, see references/options.md.
Validating sub-schemas
Target a specific path within a schema:
validator.validate(carData, fullSchema, { schemaPath: 'definitions.car' });
Browser usage (UMD)
<script src="node_modules/z-schema/umd/ZSchema.min.js"></script>
<script>
var validator = ZSchema.create();
try {
validator.validate({ name: 'test' }, { type: 'object' });
} catch (err) {
console.log(err.details);
}
</script>
TypeScript types
All types are exported from the package:
import type {
JsonSchema, // Schema type (all drafts union)
ZSchemaOptions, // Configuration options
ValidateOptions, // Per-call options (schemaPath, includeErrors, excludeErrors)
ValidateResponse, // { valid: boolean, err?: ValidateError }
SchemaErrorDetail, // Individual error detail
ErrorCode, // Error code string literal type
FormatValidatorFn, // (input: unknown) => boolean | Promise<boolean>
SchemaReader, // (uri: string) => JsonSchema
} from 'z-schema';
import { ValidateError } from 'z-schema';
Reference files
- references/error-codes.md — Full error code list with descriptions and examples
- references/options.md — Complete options reference with defaults
- references/draft-comparison.md — Feature comparison across JSON Schema drafts
Important conventions
- Always use
ZSchema.create(options?)— nevernew ZSchema(). The factory returns the correctly typed variant. - Error details are on
.details(not.errors). - Import types with
import type { ... }and values withimport { ValidateError }. - Default draft is
draft2020-12. Specify explicitly if targeting an older draft.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/zaggino/z-schema/validating-json-data">View validating-json-data on skillZs</a>