Case Study 2: MedClaim Copay Calculation Crisis

Background

MedClaim Health Services processes 500,000 insurance claims per month. In February 2026, the member services team reports a surge in member complaints: "My Explanation of Benefits says I owe $375 for a routine office visit. That can't be right."

Sarah Kim investigates and discovers that the CLM-ADJUD (claim adjudication) program is producing incorrect member responsibility amounts for approximately 3% of all claims — about 15,000 claims per month.

The Investigation

Sarah traces a sample claim through the adjudication logic:

  • Allowed amount: $150.00
  • Deductible remaining: $200.00 (member has not yet met their deductible)
  • Expected member responsibility: $150.00 (claim is entirely below remaining deductible)
  • Actual calculated amount: $350.00

The $350.00 is clearly wrong. Sarah examines the adjudication code:

      *--- The buggy code ---
       01  WS-ADJUD-FIELDS.
           05  WS-ALLOWED-AMT      PIC S9(7)V99 COMP-3.
           05  WS-DEDUCT-REMAINING PIC 9(5)V99 COMP-3.
           05  WS-COPAY            PIC 9(3)V99 COMP-3.
           05  WS-AFTER-DEDUCT     PIC 9(7)V99 COMP-3.
           05  WS-PLAN-PAYS        PIC 9(7)V99 COMP-3.
           05  WS-MEMBER-RESP      PIC 9(7)V99 COMP-3.

       PROCEDURE DIVISION.
       ADJUDICATE-CLAIM.
           COMPUTE WS-AFTER-DEDUCT =
               WS-ALLOWED-AMT - WS-DEDUCT-REMAINING
           IF WS-AFTER-DEDUCT < ZERO
               MOVE ZERO TO WS-AFTER-DEDUCT
               MOVE WS-ALLOWED-AMT TO WS-MEMBER-RESP
           ELSE
               SUBTRACT WS-COPAY FROM WS-AFTER-DEDUCT
               COMPUTE WS-PLAN-PAYS ROUNDED =
                   WS-AFTER-DEDUCT * .80
               COMPUTE WS-MEMBER-RESP =
                   WS-ALLOWED-AMT - WS-PLAN-PAYS
           END-IF

The Root Cause

Sarah identifies two critical bugs:

Bug 1: Missing S on WS-AFTER-DEDUCT. The field is declared as PIC 9(7)V99 (unsigned). When WS-ALLOWED-AMT ($150.00) minus WS-DEDUCT-REMAINING ($200.00) produces -$50.00, the negative sign is dropped. WS-AFTER-DEDUCT becomes $50.00 instead of -$50.00.

Bug 2: The IF check is meaningless. Because WS-AFTER-DEDUCT cannot be negative (no sign), IF WS-AFTER-DEDUCT < ZERO is never true. The ELSE branch always executes, even when it should not.

So the calculation proceeds with WS-AFTER-DEDUCT = $50.00 (should be zero), subtracts the copay, calculates 80% as the plan payment, and produces an inflated member responsibility.

Bug 3 (discovered later): WS-COPAY is also unsigned. If the copay subtraction would produce a negative WS-AFTER-DEDUCT, the sign is again lost.

The Fix

James Okafor and Sarah write the corrected version:

       01  WS-ADJUD-FIELDS.
           05  WS-ALLOWED-AMT      PIC S9(7)V99 COMP-3.
           05  WS-DEDUCT-REMAINING PIC S9(5)V99 COMP-3.
           05  WS-COPAY            PIC S9(3)V99 COMP-3.
           05  WS-AFTER-DEDUCT     PIC S9(7)V99 COMP-3.
           05  WS-PLAN-PAYS        PIC S9(7)V99 COMP-3.
           05  WS-MEMBER-RESP      PIC S9(7)V99 COMP-3.
           05  WS-VERIFICATION     PIC S9(7)V99 COMP-3.

Key changes: 1. Every numeric field now has S (signed) 2. The IF condition now works correctly 3. A verification step ensures plan-pays + member-resp = allowed-amount 4. ON SIZE ERROR is added to every COMPUTE

The Aftermath

  • 15,000 claims per month were incorrectly adjudicated for approximately 18 months
  • Total overcharges to members: approximately $2.1 million
  • Remediation: MedClaim reprocessed all affected claims and issued refund checks
  • Root cause in post-mortem: The original developer used PIC 9 (unsigned) as a default and did not consider negative intermediate results

James Okafor implements a new coding standard: "Every numeric field that participates in subtraction or could receive a negative result MUST have PIC S. Code review must verify this. No exceptions."

The Broader Lesson

This bug persisted for 18 months because: 1. It only affected claims where the deductible exceeded the allowed amount (~3%) 2. The incorrect amounts were plausible — they were not obviously absurd 3. The field declarations were in a copybook, far from the PROCEDURE DIVISION code 4. No verification step confirmed that plan-pays + member-resp = allowed-amount

The verification step — a simple ADD and comparison — would have caught the bug immediately on the first claim it affected.

Discussion Questions

  1. How would ON SIZE ERROR have helped catch this bug? Would it have triggered? Why or why not?
  2. The bug affected 3% of claims. What characteristics of those claims made them vulnerable?
  3. James implements a coding standard requiring S on all numeric fields. Is there any case where S should intentionally be omitted?
  4. How would you design an automated test to catch this type of bug? What test cases would you use?
  5. The remediation required reprocessing 270,000 claims. What challenges would this reprocessing involve?