Here’s how to kill patients:
<code code="4683L" codeSystem="18.104.22.168.2001.1005.22"
codeSystemName="Australian PBS Code"
displayName="Kaltostat (168212) 7.5 cm x 12 cm dressing medicated" />
<id root="22.214.171.124.2001.1005.23" extension="CC"
assigningAuthorityName="Australian PBS Manufacturer Code" />
This is a fragment of a presription taken from a real CDA document (not in a production system, though).
The problem here is that the code and the name identify different medications. Presumably, the prescriber intended one, and the software supplied the other in error.
Now in this case, it’s most likely that anyone handling this prescription will notice. There’s 2 cases:
- The prescriber intended to prescribe an anti-hypertensive, but the software provided the wrong code, and the receiver sees to apply a dressing instead
- The prescriber intended to specify a dressing, but the receiver sees to administer an anti-hypertensive instead.
Now these are sufficiently different that the dispenser or adminsterer will almost certainly notice. Especially when the instructions say “Apply to wound as directed, replace when strike through occurs initially daily but then no longer than every 7 days until wound has healed.”
But what if the 2 medications weren’t that different in terms of form or adminstration method, but still very different in terms of metabolic effect? Quite likely, the wrong medication would be prescribed.
The error in this case is that the <name>Atenolol</name> has wrongly appeared in the data – it’s a carry over from the previous document where “Atenolol” was the correct value. This is a software bug. The downstream consequences are quite unpredictable, since the information is provided both wrongly and rightly. It depends what the consumer of the information is shown.
Aside: Carry-over like this is the source of the most dangerous clinical safety issues I’ve seen, including in production systems. How does carry-over like this occur?
- Using global variables (or writing temporary files to fixed names)
- Not clearing out memory ruthlessly or initialising objects/records properly (including compiler bugs)
- re-using an document object model for multiple cases instead of recreating it
- not understanding the difference between mutable and immutable objects (or failing to protect against the side effects of this problem – or sharing immutables between object models when you think you’ve protected enough)
- Allowing threads to exist at all (or, since there’s not a lot of choice, failing to 100% get your thread contention management right. 99.999% is not good enough – a typical clinical system does 1000000+ transactions a week, so my rule of thumb is that one in a million is once every week)
- Wrong test conditions in population code (possibly combined with the above things as well)
Irrespective of those things above, this can only occur when there’s a failure in process as well – any vendor selling clinical software needs defense in depth against these kinds of errors, and many others as well. Testing, in particular, but it’s very hard to test concurrency based issues at all – prevention is way better than detection with these. More than anything else, developers need to be empowered and encouraged to put everything else aside and chase clinical safety bugs anytime they get a whiff of them. These bugs kill people. In the worst case, wrong data is associated with a patient, and the patient clinical situation is equivocal, and the wrong data is decisive, and the consequent wrong treatment kills the patient. I’ve seen this.
Note that it’s also possible that this is a user transposition or copy/paste error. I’ve seen lots of them too, though this case isn’t one. Computers don’t make those by mistake very often, but when they do…. it’s really pernicious.
But what I really wanted to talk about with this case is the issue of duplicated data.
Clinical Safety and Duplicated Data
Duplicated data is common in HL7 formats. Narrative /data in CDA. The same in FHIR. The coding data types in v2, v3/CDA, and FHIR). Code vs name in various RIM classes and v2 segments. Names vs identifiers everywhere. And this isn’t an HL7 practice either. DICOM and IHE do it – really, at this level, DICOM, HL7, and IHE are all one community. The standard themselves – v2, v3, CDA, FHIR, Dicom, etc – all come with human readable and computer processible formats.
But outside this it’s common practice too – and html page with embedded links or micro-data (first is ubiqutious, the second is less common). Word Documents with properties – it’s a ubiquitous thing in IT, because we have two consumers with radically different capabilities: computers and humans.
However, we still regularly hear that duplication is a clinical safety issue (see here for an older example), because in cases such as these, there’s an additional risk introduced by the difficulty of keeping the two forms in sync, and the problem of different systems using different parts of the output and getting different outcomes.
Yes, that’s a problem.
But how much of a problem? I think it’s rather fractional. It’s not that I think that it’s easy to keep different things in synchronisation with each other – that might the hardest problem of all in IT. It’s more than keeping things synchronised is just as much a problem in a linear process (transforming from your database to the exchange format), and multiplying the independent information paths through the path (2 fields derived from a single fact earlier in the process) simply means that your problems are more likely to detectably leak as well. And given that detection/characterisation is the hardest part of production bug hunting, that’s not a bad thing.
For instance, if the user picks a code in the UI, it’s the developers challenge to correctly reflect that code in a v2 message. That involves a sequence of steps – typically, I’d expect 20 or so steps to take if I was adding a new look up code to a UI in order to put it in a message. At some stage, for any of these formats, I’m going to have to present both the code, and some description text for it. Once I do that, I need to maintain these in parallel as I move through the process. It’s possible that the code/text split will be in the UI, in which case the synchronicity will be the users problem, but usually, the split is performed in the code.
This example is a case in point with regard to detection – there’s a logic error there somewhere. It almost certainly would’ve been a problem in production if it had got that far, but the increased visibility meant that it was detected early. Btw, it’s not my job to find this particular bug, and I can’t describe further, but I think this one has a genuine underlying error.
So duplication leads to an increase in bugs, but it makes bugs much easier to detect and characterise. So I think it’s about a neutral outcome for clinical safety. That’s good, since the desire to do it is driven by solid clinical usability desires.
Btw, this does suggest that there’s an opportunity to develop clinical safety surveillance programs that detect bugs by cross comparing code and text in exchange streams, though think that there’s some pretty big challenges there to get the signal/noise ratio high enough to be useful.