When an OperationOutcome Should Be an Alert vs a Log

Not every OperationOutcome deserves an alert, and not every one deserves to be logged and forgotten. Somewhere in the middle is where the alerting policy lives, and getting it right is the difference between an on-call rotation that stays sharp and one that develops alarm fatigue. The site's OperationOutcome reader surfaces each outcome's severity so a routing rule can be built on top. For the wider FHIR framing, the rest of the clinical FHIR series has more.

The Simple Cases

  • Fatal → always alert. Something stopped, and downstream systems need to know.
  • Information → always log-only. It is context, not a signal.

The middle two — error and warning — are where the interesting decisions live.

Error: Alert When Novel, Log When Familiar

An error that has never been seen before deserves an alert. An error that fires ten times a minute for the same known cause deserves a rate limit — alert once per window, log the rest.

The mechanism: a rolling window of seen (code, expression-path, severity) fingerprints. New fingerprint → alert. Repeat fingerprint within window → log with count. That single rule turns a screaming rotation into a useful one.

For the per-code triage, severity vs diagnostic details: which one drives your next step is the entry.

Warning: Alert When Aggregate Crosses Threshold

A single warning almost never justifies an alert. A rate of warnings that spikes above a threshold does. The right pattern: keep a rolling count of warnings by fingerprint, alert when the rate crosses N per minute.

Warnings often signal upstream drift — a validator got stricter, a schema changed, a client started sending a new shape. Aggregate warnings tell you drift is happening; individual warnings do not.

Some Codes Deserve Special Routes

  • security at error severity — alert the security team, not on-call
  • duplicate at error severity — usually a race; log and let the retry logic handle
  • not-supported at error severity — alert if it fires from your own code (bug); log if from a client
  • code-invalid at error severity — often terminology drift; monitor the rate

Building the routing into a small table lets each rule evolve independently. For the enumeration of codes and their fixes, issue.code vocabulary and what it actually means is the reference.

Include The Fingerprint In The Alert

Alerts that carry just "OperationOutcome error" are useless. Alerts that carry the (code, severity, expression, first-line-of-diagnostics) fingerprint are actionable. Same three or four fields, dramatically different signal quality.

The alert should also carry the counter — "this is fire number 47 in the last hour" is different from "first-ever occurrence". The counter tells on-call whether to investigate now or in the morning.

Distinguish Server-Origin From Client-Origin

An OperationOutcome from your own server code is a bug in your code. An OperationOutcome from a client's request is a bug in the client — or, occasionally, in the spec adherence of your validator.

Route them differently. Server-origin outcomes go to the team that owns the code path. Client-origin outcomes go to the team that supports the client. Mixing them means both teams read alerts they cannot act on.

The Log Format Matters

Every OperationOutcome logged should be searchable by (severity, code, expression). That means logging them as structured JSON, not as pretty-printed prose. The support team's ability to find "all instances of code-invalid on Patient.gender in the last week" depends on it.

For the support-facing pattern, OperationOutcome patterns that help your support team covers the mechanics.

The Short Version

Fatal alerts, information logs, error alerts on novelty, warning alerts on rate. Fingerprint the outcome. Route by origin. Log as structured JSON. That is the alerting policy that survives volume. For batch cases, aggregating OperationOutcomes across a batch is the entry.

Dataviz-particles diagram of an alert-or-log decision tree for OperationOutcome with severity, novelty, rate, and origin as the four branches, on a light navy field with dataviz-blue accents

Sources