Skip to content

Validation Rules

A Validation Rule reads the body of a Rule, Template, or Script and reports anything it finds. Findings appear as squiggles under the offending text and as entries in the Problems panel, labeled EPM Validation with the rule id in parentheses:

This `FIX(` has no matching `ENDFIX`.
EPM Validation(calc/fix-balance)

The rule id in the Problems panel is clickable. A built-in rule opens its own page here. A custom rule opens whatever documentation link it declares, and this overview when it declares none.

EPM Workbench ships with 12 built-in rules. You can change the severity of any of them, turn any of them off, add your own, and excuse a single artifact from a single rule. Nothing is pinned.

Every rule runs at one of three severities:

SeveritySquiggleEffect
errorRedStops Execute with a warning that lists the findings. You can choose to continue anyway, or cancel and fix them.
warningYellowReported, never blocking.
infoBlueReported quietly, never blocking.

A rule can also be set to off, which stops it running in that scope.

Severity is a setting, not a property of the rule. If your team treats calc/require-updatecalc-off as a hard stop, set it to error. If a rule is noise for the way your application is built, turn it off.

Free validates the rule file you have open. Built-in rules, custom rules, and Exceptions all apply to it, so a finding you see on Full Access is the same finding you see on Free.

Offline and Full add three things:

  • The workspace-wide scan, so every Rule, Template, and Script in the Pod is validated, not only the file in front of you.
  • The Validation Rules panel, where you set severities per scope, author custom rules, and manage Exceptions.
  • Adding new Exceptions, from the panel or the lightbulb quick fix. Exceptions someone already added still apply on Free.

See Seat Keys for how to activate a paid tier.

Validation Rules are configured in files named validation-rules.json. There are three scopes, from broadest to narrowest:

  1. Global, in the epmwb-global folder at your EPM Workbench Root. Applies to every Pod in the workspace.
  2. Domain, in a Domain folder. Applies to every Pod in that Domain.
  3. Pod, in the Pod Folder. Applies to that Pod only.

None of these files has to exist. A scope with no file contributes nothing.

The three combine in a fixed way:

  • Severities: the nearest scope wins. A Pod can set a rule back to error that its Domain turned off, and a Domain can raise a severity the Global file set lower.
  • Custom rules: additive. Rules defined at any scope are available to the Pods under it. If two scopes define the same rule id, the nearest one is the one that runs.
  • Exceptions: additive, and never overridden. An Exception written at the Global scope cannot be revoked by a Domain or a Pod.

To author a rule, see Creating Rules. To decide which scope a rule belongs in and get it to your colleagues, see Sharing Rules.

An Exception excuses one artifact from one rule, with a reason you write down. Use it when a rule is correct in general but wrong for a specific Rule: the archive script that really does need SET UPDATECALC ON, the Template that is a fragment and not a whole calculation.

To add one, put the cursor on the finding, open the lightbulb (Ctrl+. / Cmd+.), and choose Add Validation Exception for …. EPM Workbench asks for a reason, then writes the Exception into the scope you pick. The reason is required, because an unexplained opt-out is indistinguishable from a mistake six months later.

Exceptions for a rule are listed in the Exceptions column of the Validation Rules panel, and can be removed there.

These are the 12 rules that ship with EPM Workbench. Each has its own page with the reasoning, examples of what it flags, and how to configure it. The full catalog with default severities is at Default Rules.

calc/member-exists: every member referenced in the script exists in the application, and no alias is ambiguous. Details

calc/fix-balance: every FIX has a matching ENDFIX. Details

calc/exclude-balance: every EXCLUDE has a matching ENDEXCLUDE. Details

calc/fix-trailing-comma: no trailing comma inside a FIX / FIXPARALLEL / EXCLUDE member list. Calc Manager fails with a generic error that never points at the comma. Details

calc/require-updatecalc-off: the script sets SET UPDATECALC OFF; so Intelligent Calculation cannot skip blocks. Details

calc/require-aggmissg-on: the script sets SET AGGMISSG ON; so cleared children aggregate to parents. Details

calc/require-emptymembersets-on: the script sets SET EMPTYMEMBERSETS ON; so an empty FIX does not run against the whole cube. Details

calc/createblockoneq-paired: SET CREATEBLOCKONEQ ON is turned back off after the statements that need it. Details

calc/createnonmissingblk-paired: SET CREATENONMISSINGBLK ON is turned back off after the statements that need it. Details

calc/all-dimensions-accounted: every dimension is either inside a FIX member list or the anchor of an assignment block. Details

groovy/rtp-declared: every Run-Time Prompt read through the rtps binding is declared by the Rule. Details

groovy/macro-resolves: every %Template / %Script / %Rule macro names an artifact that exists in this Pod. Details