Profiles·Public

jsonschema

semver>=1.0.0postconditions10functions4last verified2026-06-24coverage score100%

Postconditions: what we check

  • validate · validate-throw-first
    error
    Whenoptions.throwFirst is set and validation fails
    ThrowsValidatorResultError with validation errors
    Required handlingCaller MUST wrap validate() calls with throwFirst option in try-catch. When throwFirst is set, the validator will throw ValidatorResultError at the first validation error. Without try-catch, invalid data causes unhandled exceptions and application crashes.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • validate · validate-throw-all
    error
    Whenoptions.throwAll is set and validation fails
    ThrowsValidatorResultError with all validation errors
    Required handlingCaller MUST wrap validate() calls with throwAll option in try-catch. When throwAll is set, the validator will collect all validation errors and then throw ValidatorResultError. Without try-catch, invalid data causes unhandled exceptions.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • validate · validate-throw-error
    error
    Whenoptions.throwError is set and validation fails
    ThrowsValidationError at first validation failure
    Required handlingCaller MUST wrap validate() calls with throwError option in try-catch. When throwError is set, the validator will throw ValidationError immediately at the first failure. Without try-catch, invalid data causes unhandled exceptions.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • validate · validate-invalid-schema-argument
    error
    Whenschema argument is null, undefined, a string, number, or other non-object/non-boolean type
    ThrowsSchemaError('Expected `schema` to be an object or boolean')
    Required handlingCaller MUST ensure the schema argument is a valid object or boolean before calling validate(). Passing null, undefined, a string, or any other primitive throws SchemaError synchronously. This commonly occurs when schemas are loaded from external sources (databases, HTTP APIs, config files) without validation of the loaded value. The call site MUST have try-catch or pre-validate the schema.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • validate · validate-unknown-attribute-throws
    warning
    Whenoptions.allowUnknownAttributes is false and schema contains an unrecognized keyword
    ThrowsSchemaError('Unsupported attribute: <key>')
    Required handlingWhen using allowUnknownAttributes:false with externally-provided or dynamic schemas, caller MUST wrap in try-catch. Unknown JSON Schema keywords (custom or future draft keywords not implemented by this library version) cause SchemaError to be thrown synchronously. This is a strict-mode option — callers who set it accept stricter schema validation but must handle the resulting throws.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • validate · validate-result-unchecked
    warning
    Whenvalidate() is called without throw options and the return value's .valid property or .errors array is never inspected
    Throwsnothing — silent data accepted as valid
    Required handlingWhen validate() is called without throwFirst/throwAll/throwError options, it returns a ValidatorResult object. Callers MUST check result.valid (or result.errors.length) before proceeding. If the result is discarded or only used for its instance value without checking validity, invalid data silently passes validation. This is the most common misuse pattern: calling validate() for its side-effects while assuming success. Pattern to avoid: validate(data, schema); // result discarded — data used regardless
    costhighin prodsilent failureusers seelost datavisibilitysilent
    Sources[3][1]
  • Validator.validate · validator-validate-throw
    error
    Whenthrow options are set and validation fails
    ThrowsValidatorResultError or ValidationError depending on options
    Required handlingCaller MUST wrap Validator.validate() calls with throw options in try-catch. Same behavior as standalone validate() - throws when throwFirst, throwAll, or throwError options are enabled.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • Validator.validate · validator-validate-unresolved-ref
    error
    Whenschema uses $ref URI that was not pre-registered with addSchema()
    ThrowsSchemaError('no such schema <uri>')
    Required handlingWhen Validator.validate() encounters a $ref in the schema, it resolves the URI against schemas registered with addSchema(). If the referenced schema was never registered, it throws SchemaError synchronously. This occurs in multi-schema setups (OpenAPI/JSON Schema $ref compositions) when a dependent schema is missing. Caller MUST ensure all referenced schemas are registered before calling validate(), and MUST wrap in try-catch when schemas come from external or dynamic sources.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • addSchema · add-schema-invalid
    error
    Whenschema is invalid or undefined
    ThrowsSchemaError when schema definition is invalid
    Required handlingCaller MUST wrap addSchema() calls in try-catch, especially when loading schemas from external sources. Invalid or undefined schemas cause SchemaError, common when loading from databases or HTTP endpoints.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[4]
  • scan · scan-duplicate-conflicting-schema
    error
    WhenTwo schemas share the same $id or id URI but have different structure/definitions. This occurs when dynamically assembling schema registries from multiple sources (config, database, HTTP) where the same schema ID appears with different content.
    ThrowsError('Schema <uri> already exists with different definition')
    Required handlingCaller MUST wrap scan() in try-catch when processing schemas from external or dynamic sources. The error is thrown as a generic Error (not SchemaError), making it easy to miss in catch(err) blocks that check instanceof SchemaError. Callers should deduplicate schemas before scanning or use a try-catch that catches all Error types.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5]

Sources

Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.

Source code
Issues & pull requests

Research notes

Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.

Sources: jsonschema

Package: jsonschema Category: JSON Schema Validation Library Research Date: 2026-03-05 Status: DRAFT - Testing for production promotion


Official Documentation

Primary Sources


Error Handling Behavior

Two Modes of Operation

The jsonschema package has dual error handling behavior:

1. Default Mode (Return Value) - MOST COMMON

Behavior: Returns ValidatorResult object Detection: ❌ Analyzer CANNOT detect missing result checks Usage: ~70-90% of developers use this pattern

var result = v.validate(instance, schema);
if (!result.valid) {
  // Handle errors via result.errors array
}

Source: https://github.com/tdegrunt/jsonschema/blob/master/README.md#usage

2. Throwing Mode (Optional) - LESS COMMON

Behavior: Throws exceptions when options are set Detection: ✅ Analyzer CAN detect missing try-catch Usage: ~10-30% of developers use throw options

Options:

  • throwFirst - Throws ValidatorResultError at first error
  • throwAll - Throws ValidatorResultError after full validation
  • throwError - Throws ValidationError at first error
try {
  var result = v.validate(instance, schema, { throwFirst: true });
} catch (error) {
  // Handle ValidatorResultError
}

Source: https://github.com/tdegrunt/jsonschema/blob/master/README.md


Error Types

ValidatorResult Object

Returned in default mode:

  • valid (boolean) - Whether validation passed
  • errors (ValidationError[]) - Array of validation errors
  • instance - The value being validated
  • schema - The schema used

Source: https://github.com/tdegrunt/jsonschema/blob/master/README.md

ValidationError Object

Each error contains:

  • path - Array showing location in nested structures
  • property - Dot-delimited path string (e.g., "instance.address.zip")
  • message - Human-readable failure description
  • schema - The specific schema keyword that failed
  • name - Keyword identifier (for localization)
  • argument - Additional context

Source: https://github.com/tdegrunt/jsonschema/blob/master/README.md

ValidatorResultError

Thrown when throwFirst or throwAll options are set:

  • Inherits from Error
  • Contains all ValidatorResult properties
  • Includes stack trace

SchemaError

Thrown by addSchema() when schema is invalid or undefined:

  • Common when loading schemas from external sources
  • TypeError: Cannot read property 'id' of undefined

Source: https://github.com/tdegrunt/jsonschema/issues/290


Common Mistakes & GitHub Issues

1. Undefined Schema Properties

Issue: Setting schema property to undefined causes TypeError Impact: Unhandled exception during validation Source: https://github.com/tdegrunt/jsonschema/issues/60

2. Missing Result Validation Check

Issue: Not checking result.valid allows invalid data to pass Impact: Silent validation failures, data corruption Pattern: Most common mistake with default mode

3. Nested Error Handling

Issue: oneOf/anyOf failures return binary state without root causes Limitation: Cannot determine which sub-schema failed Source: https://github.com/tdegrunt/jsonschema/issues/189

4. Schema Split Across Files

Issue: Multi-file schemas that work on jsonschemavalidator.net fail in npm module Source: https://github.com/tdegrunt/jsonschema/issues/175


Security & CVEs

No Direct CVEs Found

Finding: The jsonschema package (by tdegrunt) has NO known CVEs in Snyk database Note: Different from json-schema package (with hyphen) which has CVE-2021-3918 Source: https://snyk.io/advisor/npm-package/jsonschema

Deprecation Warning

Issue: Uses url.parse() which has security implications Recommendation: Should migrate to WHATWG URL API Note: No CVEs issued for url.parse() vulnerabilities Source: https://github.com/tdegrunt/jsonschema/issues/393


Package Maintenance

  • Downloads: 5,035,848 per week (influential project)
  • Maintenance: Sustainable but slow (no releases in 12 months as of Feb 2026)
  • Stability: Mature, stable API
  • Alternatives: ajv, joi, yup (all have similar analyzer limitations)

Source: https://snyk.io/advisor/npm-package/jsonschema


Analyzer Capability

Detection Rate: ~10-30% (Throwing mode only)

Why Low Detection:

  • Default behavior is return-value based (70-90% usage)
  • Analyzer only detects try-catch patterns (throwing mode)
  • Analyzer cannot detect missing result.valid checks

What Analyzer CAN Detect:

  • ✅ Missing try-catch when throwFirst/throwAll/throwError options used
  • ✅ Missing try-catch around addSchema() calls

What Analyzer CANNOT Detect:

  • ❌ Missing result.valid checks (default mode - most common)
  • ❌ Ignoring result.errors array
  • ❌ Silent validation failures

Contract Design Rationale

This contract focuses on the throwing mode because:

  1. Analyzer can only detect try-catch patterns (throwing mode)
  2. Default mode (return-value) requires analyzer enhancement
  3. Better to document partial coverage than no coverage

Trade-off: Contract will have low detection rate for default mode but provides value for throwing mode usage.

Future Enhancement: When analyzer supports return-value checking:

  • Add postconditions for missing result.valid checks
  • Increase detection rate to 80-90%
  • Cover the majority usage pattern

Testing Methodology

Test Fixtures Created

  1. proper-error-handling.ts

    • Throwing mode with try-catch (SHOULD PASS)
    • Default mode with result checking (SHOULD PASS)
  2. missing-error-handling.ts

    • Throwing mode without try-catch (SHOULD FAIL)
    • Default mode without checking (analyzer cannot detect)
  3. instance-usage.ts

    • Validator class usage patterns
    • Both proper and improper patterns
  4. edge-cases.ts

    • Mixed mode usage
    • Complex scenarios

Expected Results

For throwing mode usage (throwFirst/throwAll/throwError):

  • Analyzer SHOULD detect missing try-catch
  • Expected violations: 5-9 (one per unprotected throw call)

For default mode usage:

  • Analyzer CANNOT detect missing result checks
  • No violations expected (limitation documented)

Real-World Usage Patterns

Based on GitHub code search and npm registry analysis:

Common Pattern 1: Default Mode (70%+)

function validateUser(data) {
  const result = validator.validate(data, userSchema);
  if (!result.valid) {
    return { error: result.errors };
  }
  return { data };
}

Common Pattern 2: Throwing Mode (10-20%)

function validateUser(data) {
  try {
    validator.validate(data, userSchema, { throwFirst: true });
    return { data };
  } catch (error) {
    return { error: error.message };
  }
}

Common Mistake (10%+)

// Missing result check - silent failure
function validateUser(data) {
  const result = validator.validate(data, userSchema);
  return { data }; // Assumes validation passed!
}

Promotion Criteria

For PRODUCTION Status

Contract can be promoted to production if:

  • ✅ Analyzer successfully tests on fixtures
  • ✅ Throwing mode violations detected correctly
  • ✅ Real-world validation shows consistent behavior
  • ✅ Detection rate for throwing mode >80%
  • ⚠️ Default mode limitations clearly documented

Current Status

  • Phase 1-5: ✅ Complete
  • Phase 6: ⏳ Testing now
  • Phase 7: ⏳ Pending
  • Phase 8: ✅ Documentation complete

References

Need a different package?
Request a profile