Dataflow: Use custom variables instead of results

Intent

Use custom variables instead of results to pass values across templates without triggering circular reference errors. This enables complex calculations in workflows where multiple templates are interlinked.

Problem

Using results can lead to circular reference errors if multiple templates within a workflow (within a certain period) are using results from each other. Circular reference errors will completely block the rendering of the templates and can break an entire workflow.

Solution

If two templates need values from each other, prefer reading the relevant custom variables directly instead of relying on results. Even though the templates still reference each other, using customs avoids circular reference errors.

In some cases, this can lead to duplicated logic. When that happens, combine this pattern with a Shared Part that contains the shared calculation and is included by both templates.

Structure

Examples / Applicability

Templates within a workflow whose calculations depend on each other

  • Template A contains some easy calculations
  • Result of calculations in template A is needed in a calculation of template B
  • The outcome of the calculation in template B should be reported back into template A

→ Instead of relying on results (which can trigger a circular reference error), use custom variables as inputs and move shared calculations into a Shared Part where needed.

How to implement

  • Identify where results are used purely to pass values between templates.
  • Replace those result dependencies with custom variables (customs) as the source of truth.
  • If multiple templates need the same calculation, move that calculation into a Shared Part and include it from each template.

Pros and cons

Pros

  • Prevents circular reference issues (across periods and within workflows)
  • Updates in the source custom will be reflected immediately in the underlying templates (not static)
  • Custom variables are better for performance purposes

Cons

  • Risk of duplicate code (unless combined with shared parts)
  • Defaults cannot be taken into account (unless combined with shared parts)
  • Liquid errors when you reference a template that does not exist
  • Custom variables are also a chain in the chain of dependencies