In the real world, fields don’t always have a value. A customer order might come in without a shipping notes field, or an apartment number, or a custom tag. BGL has a small but specific set of tools for working with these missing values — the keyword blank, the optional-chaining ? suffix, and a few patterns that come up often.
What “missing” looks like
A missing value is blank. It’s BGL’s way of saying no value, similar to null in other languages. You can:
-
Set a field to blank to clear it:
set order.notes to blank -
Compare to blank:
when order.notes is blank then ... end
Comparing a string field to "" is not the same as comparing to blank. Empty string is a value (the zero-character string); blank means there’s no value at all.
Setting a field to blank
set order.discount_amount to blank
set order.custom.special_instructions to blank
Use this when you want to clear a value rather than overwrite it with something else.
Detecting a blank field
when order.custom.shipping_notes is blank then
set order.custom.shipping_notes to "(no special instructions)"
end
when order.subtotal is_not blank and order.subtotal > 100.0 then
...
end
The second example shows a defensive pattern — check the field exists before doing math on it. (Doing math on blank is generally fine but produces a blank result; a comparison against blank evaluates as you’d expect false.)
Optional chaining with ?
For a few fields, BGL exposes a question-mark form that returns true/false based on whether the field is set:
order.is_shipping_address_apartment?
Use this in a condition to check whether the field has a value, without needing to compare it explicitly.
when order.custom.shipping_notes? then
set order.custom.priority to "review"
end
The ? form isn’t available on every field — it’s a per-attribute affordance and most useful for boolean-ish fields where “is it set?” is a meaningful question.
Common defensive patterns
Default-then-override:
set order.custom.tier to "standard"
when order.subtotal > 500.0 then
set order.custom.tier to "premium"
end
Setting a default first means the field always has a value, regardless of whether the override matches.
Null-safe arithmetic:
when
order.discount_amount is_not blank
and order.discount_amount > 0
then
set order.custom.had_discount to true
end
Null-safe string concatenation:
set $part to "(none)"
when order.notes is_not blank then
set $part to order.notes
end
set order.custom.combined_note to "Notes: " & $part
If you concatenate blank with &, the result is also blank — which can quietly produce a blank field downstream. The pattern above avoids that.
What BGL doesn’t have
BGL is intentionally minimal here. There’s no:
-
Null-coalescing operator (
??in some languages). The default-then-override pattern is the workaround. -
Optional chaining for arbitrary nested access. You can’t write
order.shipping_address?.country?to safely walk a chain that might be missing. If you have a chain of fields that might not all exist, use a sequence ofis_not blankchecks before reading them. -
nullas a separate concept fromblank. There’s justblank.
If your rule keeps running into “the field isn’t there” issues and the workarounds are getting complex, consider whether the source integration could be configured to always include the field — sometimes the cleanest fix is upstream of the rule.
Example: a complete defensive rule
rule "Tag orders with notes"
when
order.notes is_not blank
and order.notes contains "fragile"
then
set order.custom.tag to "fragile"
end
end
The is_not blank check guards the contains, so you don’t ask “does blank contain ‘fragile’?” — which would just return false but obscures intent. Being explicit about the missing case makes the rule easier to read and audit.
Comments
Please sign in to leave a comment.