Skip to content

Conversation

@glichtner
Copy link

@glichtner glichtner commented Jan 29, 2026

Problem

When a child profile inherits from a parent that defines an extension slice (e.g., on content.component.extension in the example below), and the child adds its own slicing on a parent element (e.g., content with an outcome slice), the inherited extension slice incorrectly appears in the child's differential under the new slice path (which later leads to validation errors in the IG Publisher).

How to reproduce

Minimal reproduction case: https://github.com/glichtner/fsh-extension-slice-repro

Extension: MyExtension
Id: my-extension
Context: Element
* value[x] only string

Profile: Parent
Parent: ArtifactAssessment
Id: parent
* content
  * component
    * extension contains MyExtension named MyExtension 0..*

Profile: Child
Parent: Parent
Id: child
* content ^slicing.discriminator.type = #value
* content ^slicing.discriminator.path = "type"
* content ^slicing.rules = #open
* content contains outcome 0..1
* content[outcome]
  * type 1..1

Expected

The Child profile's differential should only contain elements that were actually constrained:

"differential": {
    "element": [
      {
        "id": "ArtifactAssessment.content",
        "path": "ArtifactAssessment.content",
        "slicing": {
          "discriminator": [
            {
              "type": "value",
              "path": "type"
            }
          ],
          "rules": "open"
        }
      },
      {
        "id": "ArtifactAssessment.content:outcome",
        "path": "ArtifactAssessment.content",
        "sliceName": "outcome",
        "min": 0,
        "max": "1"
      },
      {
        "id": "ArtifactAssessment.content:outcome.type",
        "path": "ArtifactAssessment.content.type",
        "min": 1
      }
    ]
  }

Actual

The differential incorrectly contains the inherited extension slice:

  "differential": {
    "element": [
      {
        "id": "ArtifactAssessment.content",
        "path": "ArtifactAssessment.content",
        "slicing": {
          "discriminator": [
            {
              "type": "value",
              "path": "type"
            }
          ],
          "rules": "open"
        }
      },
      {
        "id": "ArtifactAssessment.content:outcome",
        "path": "ArtifactAssessment.content",
        "sliceName": "outcome",
        "min": 0,
        "max": "1"
      },
      {
        "id": "ArtifactAssessment.content:outcome.type",
        "path": "ArtifactAssessment.content.type",
        "min": 1
      },
      {
        "id": "ArtifactAssessment.content:outcome.component.extension:MyExtension",
        "path": "ArtifactAssessment.content.component.extension",
        "sliceName": "MyExtension"
      }
    ]
  }

Cause

In cloneChildren(), when recaptureSliceExtensions=false, extension slices retain their original _original via e.clone(false), but the cloned element's id is updated to include the new slice prefix. Since id is compared in hasDiff(), this mismatch causes the inherited extension slice to appear in the differential even though nothing actually changed.

Suggested fix

Update _original.id to match the cloned element's new id when not recapturing, so the id comparison doesn't produce false positives in hasDiff().

…ntial

When a child profile inherits from a parent that defines an extension slice
and the child adds its own slicing on a parent element, the inherited
extension slice was incorrectly appearing in the child's differential.

Root cause: In cloneChildren(), when recaptureSliceExtensions=false,
extension slices retain their _original via e.clone(false), but the
cloned element's id is updated to include the new slice prefix. Since
id is compared in hasDiff(), this mismatch caused inherited extension
slices to appear in the differential even though nothing changed.

Fix: Update _original.id to match the cloned element's new id when not
recapturing, so the id comparison doesn't produce false positives.
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