fast-json-stringify icon indicating copy to clipboard operation
fast-json-stringify copied to clipboard

allOf Fails to Handle Array of if/then as Chained else Conditions

Open men232 opened this issue 5 months ago • 4 comments

Prerequisites

  • [x] I have written a descriptive issue title
  • [x] I have searched existing issues to ensure the bug has not already been reported

Fastify version

5.4.0

Plugin version

No response

Node.js version

22.14.0

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

15.5

Description

It appears that allOf cannot handle a sequence of if/then conditions as a chain of else clauses. This pattern would be extremely useful for scaling conditional validation logic, especially since libraries like AJV support it correctly.

When using allOf with an if/then block that includes array-based conditions, fast-json-stringify fails to serialize or apply logic as expected. AJV validates the same schema correctly.

When multiple if/then pairs are used inside allOf, only the first condition seems to be evaluated, and subsequent ones are ignored or misinterpreted.

Link to code that reproduces the bug

import fastJson from "fast-json-stringify";

const schema = {
  type: "object",
  properties: {
    kind: {
      enum: ["obj_1", "obj_2"],
    },
  },
  allOf: [
    {
      if: {
        properties: {
          kind: { type: "string", const: "obj_1" },
        },
      },
      then: {
        type: "object",
        properties: {
          kind: { type: "string" },
          prop_1: { type: "integer" },
        },
      },
    },
    {
      if: {
        properties: {
          kind: { type: "string", const: "obj_2" },
        },
      },
      then: {
        type: "object",
        properties: {
          kind: { type: "string" },
          prop_2: { type: "string" },
        },
      },
    },
  ],
  required: ["kind"],
};

doTest("obj 1", { kind: "obj_1", prop_1: 5 }, schema); // {"kind":"obj_1","prop_1":5} { ajv_valid: true }
doTest("obj 2", { kind: "obj_2", prop_2: "5" }, schema); // {"kind":"obj_2"} { ajv_valid: true }
doTest("obj 3", { kind: "obj_2", prop_2: 5 }, schema); // {"kind":"obj_2"} { ajv_valid: false }

function doTest(name, obj, schema) {
  const stringify = fastJson(schema);
  const validate = fastJson(obj, { mode: "debug" }).ajv.compile(schema);
  const ajv_valid = validate(obj);

  console.log(name, stringify(obj), { ajv_valid });
}

Expected Behavior

allOf should evaluate each if/then block in sequence, effectively allowing for a chain of mutually exclusive conditional branches (as a substitute for else if logic).

men232 avatar Jul 08 '25 17:07 men232