Skip to content

validateFeatureOwnedCrossSubsetting indexes the reference-subsetting list and throws (Error executing EValidator) on a feature with two crosses clauses #794

Description

@devin-ai-integration

Version: 2026-07 release (jupyter-sysml-kernel 0.61.0, KerML standalone setup). The offending lines are unchanged on master at 13c32ea.

Minimal reproduction

package TwoCrossSubsettings {
    class A {
        feature x : A;
        feature y : A;
    }
    assoc S {
        end a : A;
        end b : A crosses a.x crosses a.y;
    }
}

Validate the file on its own (no imports, no library references needed).

Expected

The grammar admits the second crosses (FeatureSpecializationPart repeats FeatureSpecialization), and validateFeatureOwnedCrossSubsetting is meant to report it as

At most one cross subsetting is allowed

on the second CrossSubsetting.

Actual

TwoCrossSubsettings.kerml:0:0: error: Error executing EValidator
TwoCrossSubsettings.kerml:9:39: error: The opposite features 'crossingFeature' of '...CrossSubsettingImpl{...@ownedRelationship.2}' and 'ownedCrossSubsetting' of '...FeatureImpl{...}' do not refer to each other

The second line is EMF's opposite-consistency check on the extra CrossSubsetting (Feature::ownedCrossSubsetting is single-valued), not the intended constraint message. Dropping the second clause (end b : A crosses a.x;) makes the model validate clean, so the second crosses is the only defect in the model.

Cause

KerMLValidator.checkFeature (org.omg.kerml.xtext/src/org/omg/kerml/xtext/validation/KerMLValidator.xtend, the validateFeatureOwnedCrossSubsetting block, line 649 at the commit above):

val crossSubsettings = f.ownedRelationship.filter[r | r instanceof CrossSubsetting].toList
if (crossSubsettings.size > 1) {
    for (var i = 1; i < crossSubsettings.size; i++)
        error(INVALID_FEATURE_OWNED_CROSS_SUBSETTING_MSG, refSubsettings.get(i), null, INVALID_FEATURE_OWNED_CROSS_SUBSETTING)
}

refSubsettings.get(i) reads the reference-subsetting list collected for the validateFeatureOwnedReferenceSubsetting check just above; with no references clause on the feature that list is empty and get(1) throws IndexOutOfBoundsException, which Xtext surfaces as Error executing EValidator. The intended target is crossSubsettings.get(i).

Found while building a differential rejection corpus for OpenSysML (cmd/pilot-reject/testdata/negative/semantic/k42-two-cross-subsettings.kerml), which runs the pinned pilot validators as its referee.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions