Property value not persisting across steps and getting recalculated on next step load

I have a 2-step flow in a case type.

In Step 1, I am generating an ID using a preprocessing data transform and displaying it in the UI as read-only.

In Step 2, I am simply displaying the same ID (read-only) without any preprocessing or additional logic.

However, when I submit Step 1 and move to Step 2, the ID value is getting regenerated/refreshed instead of retaining the value generated in Step 1.

There is no preprocessing configured in Step 2, and I am not explicitly re-triggering the ID generation logic.

What could be causing the ID to refresh between steps? Can someone help me understand why this issue is happening

This behavior is expected in Pega Constellation, and it happens because of how assignment processing and data submission work behind the scenes.

When you generate a value in an assignment’s pre-processing data transform, it is populated on the clipboard and displayed in the UI, but it is not yet persisted to the case. The value only gets saved when the assignment is submitted and the property is included in the Finish Assignment request payload.

If the field is editable, its value is sent as part of the page instructions during submission, so even though pre-processing runs again, the submitted value overwrites anything newly generated — giving the impression that the value was retained.

However, if the field is read-only or disabled, it is not included in the submission payload. When the assignment is submitted, pre-processing executes again, generates a new ID, and that new value is what gets saved to the case during commit. As a result, when you reach Step 2, you see a refreshed value.

In short:
Read-only fields don’t post values back → submission runs pre-processing again → new value gets committed → next step shows the regenerated ID.

Recommended approaches

  • Generate the ID once outside the assignment (e.g., in case creation or a utility step), or
  • Store it in a persistent property before showing it in the UI.

This ensures the value remains stable across steps.

Hope this helps.

Regards

JC

4 Likes

Move the ID generation logic to the Step 1 Post‑Processing Data Transform, or invoke a Utility shape and run the data transform before the assignment, so the value is written to the clipboard after the UI submission is processed, persisted to the database, and available for Step 2.

The general principle here is idempotency of pre-processing actions: anything that runs whenever a user opens a view should be side-effect free. The “easy button” is to just default in favor of not using pre-processing data transforms.

To elaborate…

This is a common principle in React front-ends, and it’s mostly obvious and intuitive: if I open up an assignment, I’m seeing a form that invites me to provide some input and click “submit” to take some action. It would be confusing if the mere act of opening the assignment caused the case to change — that’s why we wait for the click of the submit button to persist changes. I can open the assignment once, twice, or a hundred times and it will be the same every time until I submit it.

The mental model I use for what the submit button does is:

  1. The pre-processing data transform runs on the case.
  2. The form submission data is applied to the case.
  3. The post-processing data transform runs on the case.

When I open an assignment, I think of that screen as a preview of what the case will look like after step 1 has run. But step 1 will only run “for real” after I click submit.

Where things get less intuitive is in scenarios like the one in the OP. Generating an ID doesn’t really feel like a side-effect (maybe technically it isn’t?). Hence the awkward term “idempotence” exists to define this very specific concept:

Idempotence is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application.

This all supports an intuitive experience for end users: “nothing is permanent until I click submit.” But builders have to think carefully. For instance, ID generation is not theoretically required to be non-idempotent, and the routine could be modified to produce deterministic output given case-invariant input…

…or we can just default in favor of not using pre-processing data transforms. As I hinted above: this is my preferred solution. Speaking from personal experience, I mostly used pre-processing actions to do “utility data stuff” that didn’t really express business intent, and so I didn’t want to clutter the workflow diagram. But Live Data has pretty much categorically eliminated my need for that sort of thing. This ID generation scenario feels like a gray area to me, I could go either way on serving it through a Data Page vs. having an explicit utility workflow step to invoke it.

EDIT: I should clarify that “serving it through a Data Page” would require making the ID generation routine idempotent, which is the salient detail. I’d be more inclined to ensure idempotency if I was going to re-use the routine a lot, since the increased complexity would be offset by the gains in usage flexibility. But for a one-off I would stick to the utility shape.

2 Likes