fix(source-mysql): handle null GTID in saved CDC state and improve error message#75530
fix(source-mysql): handle null GTID in saved CDC state and improve error message#75530devin-ai-integration[bot] wants to merge 3 commits intomasterfrom
Conversation
…ror message - Fix parseSavedOffset() to treat literal "null" string from NullNode.asText() as absent - Add try-catch around GTID comparison in validate() to handle NPEs from Debezium gracefully - Route GTID NPE through abortCdcSync() so invalidCdcCursorPositionBehavior setting is respected - Improve user-facing error message in CdcPartitionsCreator to remove implementation leakage - Bump source-mysql version 3.51.5 -> 3.51.6 Co-Authored-By: bot_apk <apk@cognition.ai>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksPR Slash CommandsAirbyte Maintainers (that's you!) can execute the following slash commands on your PR:
📚 Show Repo GuidanceHelpful Resources
|
The airbyte monorepo enforces that a single PR cannot modify both the bulk CDK and a connector. Reverting CdcPartitionsCreator.kt change; the connector-level fix in MySqlSourceDebeziumOperations.kt is sufficient. Co-Authored-By: bot_apk <apk@cognition.ai>
|
|
Deploy preview for airbyte-docs ready! ✅ Preview Built with commit f9458cb. |
Co-Authored-By: bot_apk <apk@cognition.ai>
|
Deploy preview for airbyte-kotlin-cdk ready! ✅ Preview Built with commit 7bf7886. |
What
Resolves https://github.com/airbytehq/airbyte-internal-issues/issues/16114
When a MySQL CDC connection has a saved state where the GTID field is a JSON null, Jackson's
NullNode.asText()returns the literal string"null"instead of actualnull. This propagates into Debezium'sMySqlGtidSet, which then throws aNullPointerExceptionduring GTID comparison. The NPE bypasses connector-level error handling and surfaces to the user as:How
Two-layer fix in
MySqlSourceDebeziumOperations.kt:Root cause fix in
parseSavedOffset(): Filter out the literal"null"string (and blank strings) from the GTID value usingtakeUnless { it == "null" || it.isBlank() }, so it becomes actualnullbefore any Debezium API call.Defensive catch in
validate(): Wrap the GTID comparison block in atry-catch(NullPointerException)that routes throughabortCdcSync()with a descriptive message. This ensures that even if other malformed GTID edge cases exist, the error is handled gracefully and respects the user'sinvalidCdcCursorPositionBehaviorsetting.Review guide
MySqlSourceDebeziumOperations.kt— the two substantive changes (root cause fix inparseSavedOffset+ defensive catch invalidate)metadata.yaml— version bump 3.51.5 → 3.51.6docs/integrations/sources/mysql.md— changelog entry (the table whitespace reformatting is from the automatedbump_version_in_repotool, no content changes to old rows)Recommended reviewer checks:
NullPointerExceptiontoo broad? It's scoped to just the GTID comparison block, but could mask a real NPE inqueryPurgedIds()orMySqlGtidSet.subtract().NullNode.asText()does return"null"(string literal) — this is the assumed root cause.User Impact
Users who encounter a null/malformed GTID in their saved CDC state will now see:
Instead of the raw Java NPE stack trace. The outer
"Incumbent CDC state is invalid, reason: ..."prefix comes from the CDK template (unchanged in this PR) — a follow-up CDK PR could clean that up.The fix also respects
invalidCdcCursorPositionBehavior, so if the user has configured the connector to reset on invalid state, it will do so automatically rather than failing.Can this PR be safely reverted and rolled back?
Link to Devin session: https://app.devin.ai/sessions/e0b3f31174ef43b79ef5f10473488203