Skip to content

Migrate schema validation from hardcoded to based on files in local project #175

@alejandro-runner

Description

@alejandro-runner

AJV contains keyword produces false positives when used with allOf for array validation

Problem Summary

AJV incorrectly validates arrays when using multiple contains keywords within an allOf constraint. This pattern is valid JSON Schema Draft 7 but AJV produces false positives (incorrectly rejecting valid data), preventing us from using the compiled schema validators.

Current Status

Status: Workaround in place (validation hardcoded in software)
Impact: Schema validators are compiled but not used
Location: client/src/lib/reservationEvents.ts

Technical Details

Schema Structure

The schema validates a tags array where each tag is itself an array of strings. The schema requires that the tags array contains at least one tag matching each of several required patterns using contains within allOf:

{
  "tags": {
    "type": "array",
    "items": {
      "type": "array",
      "minItems": 1,
      "items": { "type": "string" }
    },
    "minItems": 1,
    "allOf": [
      {
        "contains": {
          "type": "array",
          "minItems": 2,
          "maxItems": 3,
          "items": [
            { "const": "p" },
            { "type": "string", "pattern": "^[a-f0-9]{64}$" },
            { "type": "string" }
          ],
          "additionalItems": false
        }
      },
      {
        "contains": {
          "type": "array",
          "minItems": 2,
          "maxItems": 2,
          "items": [
            { "const": "party_size" },
            { "type": "string", "pattern": "^(1[0-9]|[1-9]|20)$" }
          ],
          "additionalItems": false
        }
      },
      // ... more contains clauses
    ]
  }
}

Affected Files

  • Schemas:

    • client/src/schemas/reservation.request.schema.json
    • client/src/schemas/reservation.response.schema.json
    • client/src/schemas/reservation.modification.request.schema.json
    • client/src/schemas/reservation.modification.response.schema.json
  • Validation Code: client/src/lib/reservationEvents.ts

    • Lines 36-39: Validators are compiled but never used
    • Lines 119-153: Manual validation workaround for validateReservationRequestRumor()
    • Similar workarounds for other validation functions

AJV Configuration

const ajv = new Ajv({ 
  allErrors: true, 
  validateSchema: false  // Schema validation disabled, but issue persists
});

Dependencies

  • ajv: ^8.17.1
  • ajv-formats: ^3.0.1

Current Workaround

Manual validation is used instead of the compiled schema validators:

// Manual validation workaround in validateReservationRequestRumor()
const tags = rumor.tags;
const hasP = tags.some(t => t[0] === "p" && t[1]);
const hasPartySize = tags.some(t => t[0] === "party_size" && t[1]);
const hasTime = tags.some(t => t[0] === "time" && t[1]);
const hasTzid = tags.some(t => t[0] === "tzid" && t[1]);
// ... validation logic

Expected Behavior

The compiled schema validators (validateRequestEvent, validateResponseEvent, etc.) should correctly validate data that contains all required tag patterns. Each contains clause should independently check that at least one element in the array matches its schema.

Actual Behavior

AJV incorrectly rejects valid data, producing false positives. The validators are compiled successfully but produce incorrect results when used.

TODO Comments in Code

Multiple TODO comments reference this issue:

// TODO: Enable full schema validation once AJV strict mode issues are resolved
// The schema uses `contains` which AJV validates in a way that causes false positives
// For now, we validate required tags manually above

Related Context

This pattern is common when validating Nostr event tags (kinds 9901, 9902, 9903, 9904), where an array must contain multiple different required tag types. The schema is valid per JSON Schema Draft 7 specification, but AJV's implementation appears to have issues with this specific combination of:

  • contains keyword
  • Multiple contains clauses within allOf
  • Nested arrays (array of arrays)

Next Steps

  1. Investigate if this is a known AJV limitation or bug
  2. Test with different AJV versions to see if issue is resolved
  3. Consider alternative schema patterns that achieve the same validation goal
  4. Monitor AJV repository for fixes or workarounds
  5. Once resolved, replace manual validation with compiled schema validators

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions