What happens when parent and child classes have duplicate field names with JSON operator?

← Code Quality · Ref: Q853

When a class hierarchy uses 'default operator $$' (JSON serialization), property names must be unique across the entire hierarchy. If a parent and child class both have a field with the same name, the JSON output would be ambiguous, raising E02020.

WHY UNIQUE NAMES ARE REQUIRED

JSON keys must be unique within an object. If a parent has field 'label' and a child also has field 'label', the JSON serializer cannot produce valid output. Rather than silently picking one or producing invalid JSON, EK9 catches this at compile time.

CORRECT PATTERN

Use unique field names across the hierarchy:

  BaseConfig as open
    configName <- "default"
  ExtendedConfig extends BaseConfig
    priority <- 0

INCORRECT PATTERN

  BaseConfig as open
    label <- "default"
  ExtendedConfig extends BaseConfig
    label <- "custom"     // E02020: duplicate property

See Q200 for JSON basics. See Q202 for JSON operator patterns. See Q315 for inheritance depth.

Example

defines module qa.quality.duplicate.json.property

  defines class

    <?-
      Base configuration class with configName field.
      Uses default operator for JSON serialization.
    -?>
    BaseConfig as open
      configName <- "default"

      BaseConfig()
        -> cn as String
        configName :=: cn

      operator <=> as pure
        -> arg0 as BaseConfig
        <- rtn as Integer: configName <=> arg0.configName

      default operator

    <?-
      Extended configuration with unique field name 'priority'.
      Does NOT reuse 'configName' which would cause E02020.
    -?>
    ExtendedConfig extends BaseConfig
      priority <- 0

      ExtendedConfig()
        ->
          cn as String
          p as Integer
        super(cn)
        priority :=: p

      override operator <=> as pure
        -> arg0 as ExtendedConfig
        <- rtn as Integer: priority <=> arg0.priority

      default operator

  defines program

    JsonPropertyDemo()
      stdout <- Stdout()

      config <- ExtendedConfig("prod", 10)
      if config?
        stdout.println("Config created: " + $config)

Common mistakes

E02020 — Parent BaseConfig already has a field named configName. The child cannot reuse that name when both use default operator $$ for JSON. Use a unique field name in the child. See ek9 -h E02020 for details.

Incorrect:

    ExtendedConfig extends BaseConfig
      configName <- "custom"

Correct:

    ExtendedConfig extends BaseConfig
      priority <- 0
Other ways to ask this
  • What is E02020 in EK9?
  • Why does EK9 flag duplicate property names in JSON?
  • Can parent and child have the same field name with operator $$?
  • How does EK9 prevent ambiguous JSON output?

Coming from another language?

Java: Jackson allows field shadowing (confusing JSON). Python: no compile-time JSON validation. Kotlin: Kotlinx serialization detects some conflicts. Rust: Serde handles field shadowing but can be confusing. Go: encoding/json uses last field wins. EK9: E02020 prevents duplicate JSON property names at compile time.

Keywords: property, field, JSON, E02020, serialization, duplicate, operator, ambiguous, hierarchy, compile-time