Case Study 2: MedClaim Adjudication Logic and the Missing WHEN OTHER
Background
On a Tuesday morning in September 2023, MedClaim's claims processing batch completed without any abends — but with an alarming anomaly. Of the 18,247 claims processed overnight, 312 claims had been neither approved, denied, nor pended. They existed in a liminal state: processed by the adjudication engine but with no adjudication decision recorded.
James Okafor, MedClaim's team lead, discovered the issue during his routine morning review of batch statistics. "The numbers didn't add up," he recalled. "Approved plus denied plus pended should equal total processed. It didn't. We were 312 short."
The Investigation
James pulled the 312 orphaned claims and examined their characteristics. They all shared one thing in common: a provider type code of 'T' — telehealth provider.
MedClaim had recently onboarded telehealth providers as part of a post-pandemic expansion. The provider file had been updated with a new provider type code: 'T' for telehealth. But the adjudication EVALUATE statement had not been updated.
The offending code:
EVALUATE WS-PROVIDER-TYPE
WHEN 'P'
PERFORM 4100-PRICE-PHYSICIAN
WHEN 'H'
PERFORM 4200-PRICE-HOSPITAL
WHEN 'L'
PERFORM 4300-PRICE-LAB
WHEN 'X'
PERFORM 4400-PRICE-SPECIALIST
WHEN 'R'
PERFORM 4500-PRICE-PHARMACY
END-EVALUATE
No WHEN OTHER. When the provider type was 'T', none of the WHEN clauses matched, and the EVALUATE did nothing. Processing continued to the next step, which attempted to write the adjudication record — but since no pricing had been performed, the adjudication status field was still in its initialized state (spaces), and the record was written with an empty decision.
The Impact
- 312 claims were stuck with no adjudication decision
- $2.1 million in claim payments were delayed
- 43 providers were affected, all telehealth
- Regulatory risk: State regulations require claims to be adjudicated within 30 days; these claims were at risk of exceeding the deadline
- Member impact: 287 unique members had pending claims with no status updates, generating phone calls to customer service
The Root Cause Analysis
James convened a root cause analysis with Sarah Kim (business analyst) and Tomás Rivera (DBA). They identified a chain of failures:
- No WHEN OTHER clause in the EVALUATE — the primary technical cause
- No validation of provider type before adjudication — a missing defensive check
- No post-processing verification — the batch job did not verify that every processed claim had a decision
- Change management gap — the database team added the new provider type code, but the adjudication team was not notified
Sarah Kim's analysis was blunt: "We had four safety nets, and all four had holes."
The Fix
Immediate Fix (deployed same day)
EVALUATE WS-PROVIDER-TYPE
WHEN 'P'
PERFORM 4100-PRICE-PHYSICIAN
WHEN 'H'
PERFORM 4200-PRICE-HOSPITAL
WHEN 'L'
PERFORM 4300-PRICE-LAB
WHEN 'X'
PERFORM 4400-PRICE-SPECIALIST
WHEN 'R'
PERFORM 4500-PRICE-PHARMACY
WHEN 'T'
PERFORM 4600-PRICE-TELEHEALTH
WHEN OTHER
SET ADJ-PENDED TO TRUE
SET PEND-UNKNOWN-PROVIDER TO TRUE
MOVE WS-PROVIDER-TYPE TO WS-ERROR-DATA
PERFORM 9500-LOG-UNEXPECTED-DATA
END-EVALUATE
Systematic Fix (deployed over 6 weeks)
James's team conducted a comprehensive audit of every EVALUATE statement in the claims processing system — 147 EVALUATE statements across 23 programs. They found:
| Finding | Count |
|---|---|
| EVALUATE statements without WHEN OTHER | 34 (23%) |
| EVALUATE statements with WHEN OTHER that only logged an error | 67 (46%) |
| EVALUATE statements with WHEN OTHER that took appropriate action | 46 (31%) |
They also audited all conditional logic for defensive programming gaps:
* Added pre-adjudication validation
01 WS-PROVIDER-TYPE PIC X(01).
88 PROVIDER-PHYSICIAN VALUE 'P'.
88 PROVIDER-HOSPITAL VALUE 'H'.
88 PROVIDER-LAB VALUE 'L'.
88 PROVIDER-SPECIALIST VALUE 'X'.
88 PROVIDER-PHARMACY VALUE 'R'.
88 PROVIDER-TELEHEALTH VALUE 'T'.
88 PROVIDER-TYPE-VALID VALUE 'P' 'H' 'L'
'X' 'R' 'T'.
* In the procedure:
3000-ADJUDICATE-CLAIM.
IF NOT PROVIDER-TYPE-VALID
SET ADJ-PENDED TO TRUE
SET PEND-UNKNOWN-PROVIDER TO TRUE
MOVE 'UNKNOWN PROVIDER TYPE' TO WS-ERROR-MSG
STRING 'PROV TYPE=[' WS-PROVIDER-TYPE ']'
DELIMITED SIZE INTO WS-ERROR-DETAIL
PERFORM 9500-LOG-UNEXPECTED-DATA
GO TO 3000-ADJUDICATE-EXIT
END-IF
...
Post-Processing Verification
A new end-of-batch verification step was added:
8000-VERIFY-BATCH-TOTALS.
IF WS-APPROVED-COUNT + WS-DENIED-COUNT +
WS-PENDED-COUNT NOT = WS-TOTAL-PROCESSED
MOVE 'ADJUDICATION COUNT MISMATCH'
TO WS-ALERT-MSG
COMPUTE WS-ORPHAN-COUNT =
WS-TOTAL-PROCESSED -
WS-APPROVED-COUNT -
WS-DENIED-COUNT -
WS-PENDED-COUNT
PERFORM 9800-SEND-ALERT
END-IF
.
The Broader Lesson
This incident became a teaching moment across MedClaim. James created a one-page coding standard addendum titled "The WHEN OTHER Rule" with three mandates:
-
Every EVALUATE must have a WHEN OTHER clause. No exceptions. Code reviews must reject any EVALUATE without one.
-
Every WHEN OTHER must take a meaningful action. Logging is a minimum; where possible, WHEN OTHER should set the record to a safe state (pend, reject) rather than merely noting the anomaly.
-
Every conditional decision must be validated post-processing. If a batch processes N records, the sum of all outcomes must equal N. Any discrepancy triggers an immediate alert.
Sarah Kim summarized the lesson in terms that resonated beyond the technical team: "We didn't lose $2.1 million because of bad code. We lost it because we assumed our code knew about every possible input. It didn't. It never does."
Discussion Questions
-
The EVALUATE statement without WHEN OTHER did not cause an abend — it silently did nothing. Why is this "silent failure" mode often more dangerous than a crash?
-
The root cause analysis identified a change management gap (the database team added a code without notifying the adjudication team). How would you design a process to prevent this type of cross-team disconnect?
-
James's audit found that 23% of EVALUATE statements lacked WHEN OTHER. If you were prioritizing which ones to fix first, what criteria would you use?
-
The 88-level
PROVIDER-TYPE-VALIDacts as a "whitelist" of known values. How does this approach differ from the WHEN OTHER approach, and why might you want both? -
Consider the post-processing verification step. What are the limitations of this approach? Can you think of a scenario where the counts balance but there is still a logic error?