Summary
SchemaValidator (jhelm-core) is a hand-rolled partial JSON Schema validator that recognizes only ~10 keywords. Real Helm validates values.schema.json with a full-spec library, so charts whose schema uses anything outside jhelm's subset pass jhelm but behave differently under Helm — a silent compatibility gap.
Current state
jhelm-core/src/main/java/org/alexmond/jhelm/core/service/SchemaValidator.java implements by hand:
type, required, properties (recursive), enum
minimum, maximum, minLength, maxLength, pattern
Everything else in the schema is silently ignored, notably: $ref/$defs/definitions, additionalProperties, items / array-element validation, oneOf/anyOf/allOf/not, if/then/else, const, patternProperties, dependencies/dependentSchemas, format, multipleOf, exclusiveMinimum/exclusiveMaximum.
Enforced in two places (both call SchemaValidator.validate(chartName, schemaJson, values) and catch SchemaValidationException):
Engine.java:810-819 — on render (throws TemplateRenderException)
LintAction.java:125-137 — on lint (adds each error as a lint finding)
What upstream Helm uses
|
Library |
Draft |
| Helm 3 (release-3.x) |
github.com/xeipuuv/gojsonschema |
Draft-07 (full spec) |
Helm 4 (main) |
github.com/santhosh-tekuri/jsonschema/v6 v6.0.3 |
draft 2020-12 default (full spec) |
So jhelm doesn't even cover full Draft-07 (Helm 3's baseline), let alone Helm 4's 2020-12.
Concrete divergences (chart passes jhelm, Helm differs):
additionalProperties: false with an unknown key — Helm rejects, jhelm passes.
$ref to #/$defs/... — Helm resolves and validates, jhelm ignores.
oneOf / if-then-else conditional validation — enforced by Helm, ignored by jhelm.
- Array
items constraints — enforced by Helm, ignored by jhelm.
Proposed fix
Replace the hand-rolled validator with com.networknt:json-schema-validator (v3 API), configured for draft 2020-12 by default and $schema-aware (a chart declaring "$schema": ".../draft-07/schema#" validates as Draft-07, matching Helm 3 charts; absent $schema defaults to 2020-12, matching Helm 4).
The sibling repo yj-schema-validator already uses this exact library (json-schema-validator 3.0.5) on Jackson 3 (tools.jackson, same as jhelm) — it is the reference implementation. Core pattern (YamlSchemaValidator.getSchemaByPath / validateJsonNode):
SchemaRegistryConfig cfg = SchemaRegistryConfig.builder().build();
SchemaRegistry registry = SchemaRegistry.withDefaultDialect(
SpecificationVersion.DRAFT_2020_12, b -> b.schemaRegistryConfig(cfg));
Schema schema = registry.getSchema(schemaNode);
OutputUnit result = schema.validate(valuesJson, InputFormat.JSON, OutputFormat.LIST);
Porting requirements / caveats
- Preserve the public contract. Keep
validate(String chartName, String schemaJson, Map<String,Object> values) throwing SchemaValidationException(chartName, List<String>) so Engine and LintAction are untouched.
- Map
OutputUnit → List<String>. Walk getDetails() → each detail's getInstanceLocation() + getErrors() (keyword→message) into the existing error-string list.
- Helm float64 semantics. Helm loads values as float64, so a whole-valued double (
8080.0, 3.0) must satisfy type: integer. JSON-Schema spec says integer matches a number with zero fractional part; NetworkNT honors this — lock it with a test (jhelm renders values as boxed Doubles).
- Malformed schema → treated as absent (warn + skip), matching current behavior and real Helm.
- Cache the compiled
Schema keyed by schema content — the current code re-parses on every validate() call (SchemaValidator.java:44).
- Use the NetworkNT v3 API (
SchemaRegistry/Schema), not the older 1.x JsonSchemaFactory/ValidationMessage API most online examples show — follow yj.
- Input: serialize the
Map values via tools.jackson JsonMapper and validate with InputFormat.JSON.
Done when
SchemaValidator backed by NetworkNT, full-spec 2019-09/2020-12 (+ Draft-07 via $schema).
- Existing
SchemaValidatorTest cases stay green; new cases cover additionalProperties, $ref/$defs, oneOf/anyOf/allOf, if/then/else, items, const, the float64-integer parity case, and $schema-driven draft selection.
- Malformed-schema-as-absent preserved;
Engine/LintAction unchanged.
- Build gates green (PMD, checkstyle, tests).
Summary
SchemaValidator(jhelm-core) is a hand-rolled partial JSON Schema validator that recognizes only ~10 keywords. Real Helm validatesvalues.schema.jsonwith a full-spec library, so charts whose schema uses anything outside jhelm's subset pass jhelm but behave differently under Helm — a silent compatibility gap.Current state
jhelm-core/src/main/java/org/alexmond/jhelm/core/service/SchemaValidator.javaimplements by hand:type,required,properties(recursive),enumminimum,maximum,minLength,maxLength,patternEverything else in the schema is silently ignored, notably:
$ref/$defs/definitions,additionalProperties,items/ array-element validation,oneOf/anyOf/allOf/not,if/then/else,const,patternProperties,dependencies/dependentSchemas,format,multipleOf,exclusiveMinimum/exclusiveMaximum.Enforced in two places (both call
SchemaValidator.validate(chartName, schemaJson, values)and catchSchemaValidationException):Engine.java:810-819— on render (throwsTemplateRenderException)LintAction.java:125-137— on lint (adds each error as a lint finding)What upstream Helm uses
github.com/xeipuuv/gojsonschemamain)github.com/santhosh-tekuri/jsonschema/v6v6.0.3So jhelm doesn't even cover full Draft-07 (Helm 3's baseline), let alone Helm 4's 2020-12.
Concrete divergences (chart passes jhelm, Helm differs):
additionalProperties: falsewith an unknown key — Helm rejects, jhelm passes.$refto#/$defs/...— Helm resolves and validates, jhelm ignores.oneOf/if-then-elseconditional validation — enforced by Helm, ignored by jhelm.itemsconstraints — enforced by Helm, ignored by jhelm.Proposed fix
Replace the hand-rolled validator with
com.networknt:json-schema-validator(v3 API), configured for draft 2020-12 by default and$schema-aware (a chart declaring"$schema": ".../draft-07/schema#"validates as Draft-07, matching Helm 3 charts; absent$schemadefaults to 2020-12, matching Helm 4).The sibling repo
yj-schema-validatoralready uses this exact library (json-schema-validator3.0.5) on Jackson 3 (tools.jackson, same as jhelm) — it is the reference implementation. Core pattern (YamlSchemaValidator.getSchemaByPath/validateJsonNode):Porting requirements / caveats
validate(String chartName, String schemaJson, Map<String,Object> values)throwingSchemaValidationException(chartName, List<String>)soEngineandLintActionare untouched.OutputUnit→List<String>. WalkgetDetails()→ each detail'sgetInstanceLocation()+getErrors()(keyword→message) into the existing error-string list.8080.0,3.0) must satisfytype: integer. JSON-Schema spec says integer matches a number with zero fractional part; NetworkNT honors this — lock it with a test (jhelm renders values as boxed Doubles).Schemakeyed by schema content — the current code re-parses on everyvalidate()call (SchemaValidator.java:44).SchemaRegistry/Schema), not the older 1.xJsonSchemaFactory/ValidationMessageAPI most online examples show — follow yj.Mapvalues viatools.jacksonJsonMapperand validate withInputFormat.JSON.Done when
SchemaValidatorbacked by NetworkNT, full-spec 2019-09/2020-12 (+ Draft-07 via$schema).SchemaValidatorTestcases stay green; new cases coveradditionalProperties,$ref/$defs,oneOf/anyOf/allOf,if/then/else,items,const, the float64-integer parity case, and$schema-driven draft selection.Engine/LintActionunchanged.