Skip to content

Improve schema validation error messages with actionable context#355

Open
holodorum wants to merge 8 commits intokson-org:mainfrom
holodorum:error-message-additional-properties
Open

Improve schema validation error messages with actionable context#355
holodorum wants to merge 8 commits intokson-org:mainfrom
holodorum:error-message-additional-properties

Conversation

@holodorum
Copy link
Copy Markdown
Collaborator

  • Add property names, schema titles, source locations, and allowed values to schema validation errors so they are immediately actionable without consulting the schema
  • Fix grammar and quoting inconsistencies in existing error messages
  • Extract shared KsonValue.toDisplayString() to eliminate divergent formatting in EnumValidator and ConstValidator

Detail

Schema validation errors were generic — "Value is not one of the allowed enum values", "Additional properties are not allowed", "Expected one of: number, but got: string" — forcing the reader to cross-reference the schema to understand what went wrong.

This branch threads contextual information (property names, schema titles, item counts, allowed values, source locations) through the validators so each error message stands on its own. Eight focused commits, each with tests:

  1. additionalProperties: includes property name and schema title
  2. Sub-schema errors (anyOf/oneOf): labeled with schema titles and per-error locations
  3. additionalProperties with sub-schemas: contextual "must conform to" message
  4. enum: lists the allowed values
  5. type mismatch: includes the property name
  6. additionalItems: shows expected vs actual item counts
  7. Grammar fix: "must be a strings" → "must be strings"
  8. Quoting fix: consistent single quotes in dependency errors

The generic "Additional properties are not allowed" message gave no
indication of which property was the problem or which schema rejected
it.  The message now reads "Additional property 'foo' is not allowed
in Bar" (with the "in Bar" suffix appearing only when the schema has
a title), making it immediately actionable.
Two changes make sub-schema validation errors (anyOf/oneOf) more
actionable:

1. descriptionWithDefault() now falls back to schema title before
   the generic "JSON Object Schema", so sub-schema error groups are
   labeled distinctively when the schema author provides a title.

2. Per-sub-schema error strings now include the source location
   (line.column) of each error, so you can tell which field each
   error refers to even though the errors are rolled up into a
   single summary message.
When additionalProperties specifies a schema (e.g. a $ref to a model),
validation errors like "Expected one of: object, but got: string" give
no indication of which property failed or what schema was expected.

The validator now emits a contextual message before the schema's own
errors: "Property 'integration' must conform to 'OperationMetadataModel'"
— giving the reader both the property name and the expected schema,
so the dict-of-models pattern is immediately clear.
The generic "Value is not one of the allowed enum values" gave no
indication of what the valid choices were, forcing the reader to go
look up the schema. The message now reads
"Value must be one of: \"active\", \"inactive\", \"pending\""
— listing the allowed values directly in the error.

Extracts a shared KsonValue.toDisplayString() extension (in
ValueFormatting.kt) used by both EnumValidator and ConstValidator,
replacing the duplicated inline when blocks that had already
diverged (strings quoted vs. unquoted, different placeholder styles).
Type mismatch errors like "Expected one of: number, but got: string"
gave no indication of which property had the wrong type. When a schema
is parsed as a property schema, the property name is now threaded
through JsonObjectSchema to TypeValidator, producing messages like
"Property 'value': Expected one of: number, but got: string".

This is especially valuable in sub-schema error rollups (anyOf/oneOf)
where multiple type mismatches are listed together and the property
name is the key to understanding which alternative was intended.
The generic "Additional items are not allowed" gave no indication of
how many items the schema expected vs. how many were present. The
message now reads "Expected at most 3 items, but found 5" — making
the tuple length constraint immediately clear.
"must be a strings" → "must be strings" in both
SCHEMA_STRING_ARRAY_ENTRY_ERROR and SCHEMA_TYPE_ARRAY_ENTRY_ERROR.
SCHEMA_MISSING_REQUIRED_DEPENDENCIES used mixed backtick/single-quote
delimiters (\`foo'). SCHEMA_DEPENDENCIES_SCHEMA_ERROR had the same
issue. Both now use consistent single quotes ('foo') matching the
rest of the error messages.
@holodorum holodorum force-pushed the error-message-additional-properties branch from 646fba2 to 39cd100 Compare March 26, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant