SHOW EDIT of a subclass for an object of its superclass: the form fails to open with AssertionError

Closed Beginner friendly
#1,862 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
74/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
java
Domain
backend

Research direction

Start from the stack trace: ClassFormSelector.getStaticForm(BusinessLogics, CustomClass) in server/src/lsfusion/server/logics/form/interactive/dialogedit/ClassFormSelector.java, then CustomClass$ClassFormHolder.getPolyForm where the concreteClass.isChild assertion fires. Reproduce with the issue's .lsf snippet by opening the form under -ea (or the TestAdd form / editCIncomeDocument of the features sample). Done means the form opens and the button is predicted to show B's edit form, with the no-object getStaticForm(BL) path reused when the class is not a child of the edit class.

Written by the indexing model from the issue text.

Description

A form fails to open when it shows an action that opens the edit form of a class (SHOW EDIT B = a) for an object of a superclass of that class. With assertions enabled (-ea) the server throws while the form design is serialized, so the form cannot be opened at all, not only when the button is pressed.

CLASS A;
CLASS B : A;

editAsB 'Edit as B' (A a) {
    SHOW EDIT B = a;
}

FORM aList
    OBJECTS a = A
    PROPERTIES(a) VALUE, editAsB GRID
;

Expected: the form opens, the button is predicted to open the edit form of B.

Actual: opening aList fails:

java.lang.AssertionError
	at lsfusion.server.logics.classes.user.CustomClass$ClassFormHolder.getPolyForm(CustomClass.java:396)
	at lsfusion.server.logics.classes.user.CustomClass.getEditForm(CustomClass.java:557)
	at lsfusion.server.logics.form.interactive.dialogedit.ClassFormSelector.getForm(ClassFormSelector.java:98)
	at lsfusion.server.logics.form.interactive.dialogedit.ClassFormSelector.getStaticForm(ClassFormSelector.java:90)
	at lsfusion.server.logics.form.interactive.action.async.map.AsyncMapOpenForm.map(AsyncMapOpenForm.java:103)
	at lsfusion.server.logics.form.struct.action.ActionObjectEntity.getAsyncEventExec(ActionObjectEntity.java:60)
	at lsfusion.server.logics.form.struct.property.PropertyDrawEntity.getAsyncEventExec(PropertyDrawEntity.java:439)
	at lsfusion.server.logics.form.interactive.design.property.PropertyDrawView.getChangeType(PropertyDrawView.java:261)
	...
	at lsfusion.server.logics.form.interactive.controller.remote.RemoteForm.getRichDesignByteArray(RemoteForm.java:221)
Cause

To predict the form a button opens, AsyncMapOpenForm.map takes the base class of the form object passed to the action (A here) and calls ClassFormSelector.getStaticForm(BL, A), which calls B.getEditForm(LM, A). ClassFormHolder.getPolyForm asserts concreteClass.isChild(CustomClass.this), but A is a superclass of B, not a subclass.

The class of the form object is only an upper bound of the object passed: when it is not a subclass of the edit class, it says nothing about which poly form will open. A possible fix is to predict by the edit class itself in that case, the same as when no object is passed:

// ClassFormSelector.getStaticForm(BusinessLogics BL, CustomClass customClass)
if(customClass == null || !customClass.isChild(cls))
    return getStaticForm(BL);

When the button is pressed, ClassFormSelector.getForm takes the current class of the actual object, so B.getEditForm can still be asked for an object that is not a B; that is a call with a wrong object and is left as is.

Versions

Found on master (7.0-SNAPSHOT) as of 2026-10-07 by opening the TestAdd form of the features sample (editCIncomeDocument). The same code is in v6; not checked there on a running server.

Dominant language
Java
Stars
214
Forks
46
PR merge metrics
No merged PRs in 30d

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • No pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from lsfusion/platform

All issues in lsfusion/platform

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.