GitHub
08/31/2026, 9:38 PMget_nested_value() helper in singer_sdk/helpers/_util.py that traverses a record dictionary level by level using a dotted key path (e.g., "attributes.updated"). The _increment_stream_state() method and is_timestamp_replication_key property in singer_sdk/streams/core.py are updated to use this traversal instead of a flat dictionary lookup, enabling tap developers to point replication keys at timestamp fields nested inside sub-objects rather than only at top-level fields.
Why was this PR needed?
Many real-world APIs — including HubSpot, Salesforce, and GitHub — return timestamps nested inside sub-objects. Before this fix, setting replication_key = "attributes.updated" caused the SDK to perform a flat lookup (record.get("attributes.updated")), which returned None because no top-level key with that literal name exists. As a result, the state was never updated, and the tap silently re-synced all records on every run.
Investigation traced the root cause to two locations in `singer_sdk/streams/core.py`:
• _increment_stream_state() passed the raw record directly to increment_state(), which performed a flat key lookup returning None for dotted paths
• is_timestamp_replication_key called schema.get("properties", {}).get(replication_key) which only checked the schema's top level, incorrectly raising InvalidReplicationKeyException even when the field existed at a deeper level
The fix keeps singer_sdk/streams/_state.py unchanged by flattening the extracted value into a flat record before passing it to the state manager, limiting the scope of the change and reducing regression risk.
What are the relevant issue numbers?
Closes #1198
Does this PR meet the acceptance criteria?
• Tests added for new/changed behavior
• All tests passing
• Follows project style guide
• No breaking changes introduced
Summary by Sourcery
Enable nested replication keys throughout stream state advancement and replication-key validation.
New Features:
• Support dotted replication keys that resolve timestamp and other replication values within nested record objects.
Bug Fixes:
• Fix incremental state updates and timestamp replication-key validation for nested schema fields, preventing repeated full resynchronization when bookmarks are nested.
Enhancements:
• Add a reusable helper for traversing nested mappings with dotted key paths and distinguishing missing paths when needed.
Tests:
• Add coverage for flat, multi-level nested, missing, invalid, and non-mapping replication-key paths, including state-manager integration.
meltano/sdkGitHub
08/31/2026, 9:38 PM