Keep custom functions pure
A custom function should do one thing, depend only on its inputs, and return the same result every time for those inputs. No database reads, no API calls, no hidden state. Pure functions are the safe, reusable building blocks of transformation.
Custom functions are invoked from maps and resolved into pipeline-component property values. Those are hot, repeated, sometimes parallel call sites. A function that reaches out to an external system from inside a map turns a transformation into a chain of network calls — slow, non-deterministic, and impossible to reason about when one of them fails mid-map.
Keep each function narrow and deterministic: format a date, compute a check digit, look up a code in a static table, normalize a string. That makes it trivially testable, freely reusable across maps, and predictable for the AI engine learning from your library. When a transformation genuinely needs live external data, that is enrichment — do it as a content enricher on a port, not as a side effect buried in a function.