Docs/Infohub (Flow)/The Zero Guard
Infohub (Flow)Concept

The Zero Guard

Every division in an Infohub calculation needs protecting, and the pattern is always the same.

Updated 15 Oct 2026Infohub Docs

Division by zero is the most common cause of failed calculations in Infohub. It is also the easiest to prevent, with a single pattern applied consistently. This article explains the pattern, why the problem is routine rather than exceptional, and how the failure spreads if you leave it unguarded.

The pattern#

Every division in an Infohub calculation should take this form:

Divisor.Value == 0 ? 0 : Dividend.Value / Divisor.Value

With real measure references:

Measure_1044.Value == 0 ? 0 : Measure_1043.Value / Measure_1044.Value

Read it as: "if the divisor is zero, the answer is zero; otherwise divide." One line, no performance cost, and the calculation can no longer fail on that division.

Why zero divisors are normal, not exceptional#

It would be reasonable to assume a denominator is never zero in a working plant. In practice it is zero regularly, for at least five ordinary reasons.

The plant was not running. A production target for a shutdown day is zero. Yield is good product divided by total product, and on a maintenance day total product is zero. Every ratio in your model will meet a non-production period eventually.

A manual entry has not been filled in. Calculations that divide by a manually entered design capacity, headcount, or planned hours will divide by nothing at all until someone types the value in — and the calculation runs before they do.

The source reported zero. A flow meter reads zero when the pump is off. An instrument reads zero during a communication fault or a sensor failure. Neither is unusual.

A new measure has no history yet. For the first intervals after configuring a chain, measures above the base have no values. Anything dividing by them divides by zero or null.

A period is genuinely empty. Overnight, over a weekend, over a public holiday — real gaps, correctly recorded.

None of these are edge cases. They are Tuesday.

What happens without the guard#

An unguarded division does not just produce a wrong number for one interval. It fails, and the failure travels.

The calculation errors for that interval, so the measure has no value there. Anything aggregating from it now has a hole: the daily figure is computed from twenty-three hours instead of twenty-four, or is missing outright. Anything calculating from that inherits the gap. A single unguarded division on an hourly measure can leave a visible notch in a monthly report several layers up.

Worse, the failure is quiet. There is no red banner on the dashboard — there is simply a number that is slightly too low, or a gap that looks like a data outage. Teams have chased "the historian dropped out overnight" for weeks when the real cause was one unguarded ratio meeting one zero target.

Important

Recalculation is required after fixing. Adding the guard changes how future intervals are calculated. Intervals that already failed stay failed until you recalculate the affected range. Fix the expression, then recalculate the period that was wrong.

Return zero, or return null?#

Both are defensible, and the choice should be deliberate.

Return 0 when zero is the honest operational answer. Yield on a day with no production is arguably 0%. Consumption per tonne when nothing was produced is 0. Zero keeps the aggregation chain intact and participates predictably in sums.

Return null when the value is genuinely unknown rather than zero, and you would rather a gap were visible than have a false zero pulled into an average:

Measure_1044.Value == 0 ? (double?)null : Measure_1043.Value / Measure_1044.Value

The trap to avoid is returning 0 into an average where the value is unknown. A month of daily efficiencies where five shutdown days contribute 0% will report a monthly average materially below the true operating efficiency. If a measure is going to be averaged upward, null is usually the more truthful choice.

Guard each division, not the whole formula#

In a formula with several divisions, guard each one where it occurs rather than wrapping the entire expression in one test. Guarding individually keeps the rest of the calculation working when only one denominator is zero, and makes the expression far easier to read.

Harder to follow, and fails as a whole:

(Measure_1.Value == 0 || Measure_2.Value == 0) ? 0
    : Measure_3.Value / Measure_1.Value + Measure_4.Value / Measure_2.Value

Clearer, and degrades one term at a time:

(Measure_1.Value == 0 ? 0 : Measure_3.Value / Measure_1.Value)
  + (Measure_2.Value == 0 ? 0 : Measure_4.Value / Measure_2.Value)

Nulls need guarding too#

.Value is a nullable double. A null divisor is a different problem from a zero divisor, and == 0 does not catch it. Where a divisor may be missing entirely, handle both:

(Measure_1044.Value ?? 0) == 0 ? 0 : Measure_1043.Value / Measure_1044.Value

That single form covers zero and null together, and is the safest default when you are not certain the divisor always exists.

Use a function and stop thinking about it#

The pattern is identical every time, which makes it an obvious candidate for a custom function. Define it once:

public static double? SafeDivide(double? numerator, double? denominator)
{
    if (!denominator.HasValue || denominator.Value == 0) return 0;
    return (numerator ?? 0) / denominator.Value;
}

Then every calculation reads clearly:

SafeDivide(Measure_1043.Value, Measure_1044.Value)

This is the approach worth standardising on across a site. It removes the possibility of someone forgetting the guard, it makes the intent obvious in review, and if you later decide that null is a better return than zero, you change one function instead of hundreds of expressions.

Tip

Make it a house rule. Adopt one form — the inline ternary or a SafeDivide function — and use it everywhere. Mixed conventions make code review slower and make an unguarded division harder to spot among guarded ones.

Finding unguarded divisions in an existing model#

If you have inherited a model, the divisions that will fail are worth finding before they do.

Look for measures whose values have unexplained gaps, especially on weekends, shutdowns, and month boundaries. Cross-check any ratio measure — anything with "per", "%", "rate", "efficiency", "yield", or "utilisation" in its name — since those are all divisions. Then confirm the denominator of each is guarded.

The Config CLI can list measures and their calculation expressions, which makes a bulk audit for / without an accompanying == 0 ? or SafeDivide practical to script.

esc
↑↓ navigate · ↵ open · ⌘K anywhere