From 9570bce6ab55e68c092dd6202d83ccb746199420 Mon Sep 17 00:00:00 2001 From: afkerhousse Date: Tue, 28 Apr 2026 20:43:07 +0200 Subject: [PATCH] fix: boolean handler must not coerce None/empty-string to False transform_recur always moves null to the end of the type list so that null is tried last. For a schema type ["null", "boolean"] this means boolean is attempted first. The boolean handler previously reached bool(None) = False and returned (True, False) without raising, so the null handler was never reached. The same applied to empty strings: bool("") = False. As a result, any field typed ["null", "boolean"] whose API value was None or "" was silently written as false instead of null, corrupting data in every downstream destination. Fix: return (False, None) early in the boolean handler when data is None or "", allowing transform_recur to fall through to the null handler which correctly returns (True, None). --- singer/transform.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/singer/transform.py b/singer/transform.py index 3a9fc96..b9fabba 100644 --- a/singer/transform.py +++ b/singer/transform.py @@ -331,6 +331,12 @@ def _transform(self, data, typ, schema, path): return False, None elif typ == "boolean": + # None and "" must fall through to the null handler; bool(None) + # and bool("") both return False without raising, which would + # silently coerce null values to false for ["null", "boolean"] schemas. + if data is None or data == "": + return False, None + if isinstance(data, str) and data.lower() == "false": return True, False