Skip to content

Conversation

devin-ai-integration[bot]
Copy link
Contributor

What

Fixes issue #9633 where Google Ads connector syncs fail with "Invalid state as stream slices that are emitted should refer to an existing cursor" error.

The root cause was that ChangeStatusRetriever and CriterionRetriever were mutating StreamSlice objects during record processing, which breaks the ConcurrentPerPartitionCursor tracking mechanism.

How

  1. ChangeStatusRetriever fix: Changed cursor_slice = stream_slice.cursor_slice to cursor_slice = dict(stream_slice.cursor_slice) to create a copy before modifying it, preventing mutation of the original StreamSlice object.

  2. CriterionRetriever fix: Added associated_slice=stream_slice parameter to deleted Record objects to ensure proper cursor tracking.

The cursor validation fails because ConcurrentPerPartitionCursor uses StreamSlice objects as dictionary keys, and their hash/equality depends on the cursor_slice contents. Mutating the cursor_slice in place changes the hash, making the slice unfindable in the cursor's internal tracking.

Review guide

  1. airbyte-integrations/connectors/source-google-ads/source_google_ads/components.py - Focus on lines 449 and 534:
    • Verify that copying cursor_slice dict prevents the original StreamSlice mutation
    • Check that adding associated_slice to deleted records doesn't break existing logic
    • Consider if there are other similar mutation issues in this file

User Impact

Positive: Fixes Google Ads connector syncs that were failing with cursor validation errors, particularly affecting the campaign_criterion stream.

Potential risks:

  • Changes are in critical data flow paths without local testing
  • Fix is based on code analysis rather than reproduction of the actual error

Can this PR be safely reverted and rolled back?

  • YES 💚

The changes are minimal and localized to specific error handling paths. Reverting would simply restore the previous (broken) behavior.


Link to Devin run: https://app.devin.ai/sessions/1b6c7df5a82a49e58e813bff4dcfce13
Requested by: agarctfi

…lidation error

- Copy cursor_slice dict before modifying in ChangeStatusRetriever to avoid mutating original StreamSlice
- Add associated_slice to deleted Record objects in CriterionRetriever to ensure proper cursor tracking
- Fixes #9633: Invalid state as stream slices that are emitted should refer to an existing cursor

Co-Authored-By: unknown <>
Copy link
Contributor Author

Original prompt from API User
Comment from @agarctfi: /ai-fix\n\nIMPORTANT: The user will expect a response posted back to the PR. You should post exactly one comment back to the respective issue PR. If the user requested a code change or PR, your comment should contain a link to the PR. Assume the user has no access to your session or conversation thread unless/until you respond back to them.\n\nIssue #9633 by @wmikemoon: Python L3 - Google Ads : `Invalid state as stream slices that are emitted should refer to an existing cursor`\n\nIssue URL: https://github.com/airbytehq/oncall/issues/9633\n\nPlease use playbook macro: !issue_fix

PLAYBOOK_md:
# AI Fix Playbook

You are AI Fix Devin, an expert at reproducing and fixing Airbyte-related issues.

## Context
You are working on the issue linked above in context. You will also need to pull issue comments for full context.

## Rule: Immediate Issue Comment After PR Creation
**MANDATORY REQUIREMENT**: If you create a PR during an AI Fix workflow, your **first action** after creating the PR must be to create a comment on the originating issue. If you cannot create a PR, likewise, your action should be to comment back to the issue.

## Your Task: Reproduce and Fix

1. **Analysis**: Read the complete issue content including all comments for full context.

2. **Research**: Check the internet and Airbyte repositories for:
   - Similar issues and their solutions
   - Known bugs or limitations
   - Recent changes that might have introduced the problem

3. **Environment Setup**: Verify and set up the necessary environment:
   - Check available credentials and access
   - Set up Airbyte repositories and dependencies
   - Prepare test environment for reproduction

4. **Reproduction Attempt**: Try to reproduce the issue:
   - Follow the exact steps described in the issue
   - Document your reproduction process
   - Capture logs, errors, and diagnostic information

5. **Root Cause Analysis**: If reproduction is successful:
   - Analyze the root cause of the issue... (1686 chars truncated...)

Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Contributor

github-actions bot commented Oct 9, 2025

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

Helpful Resources

PR Slash Commands

Airbyte Maintainers (that's you!) can execute the following slash commands on your PR:

  • /format-fix - Fixes most formatting issues.
  • /bump-version - Bumps connector versions.
    • You can specify a custom changelog by passing changelog. Example: /bump-version changelog="My cool update"
    • Leaving the changelog arg blank will auto-populate the changelog from the PR title.
  • /run-cat-tests - Runs legacy CAT tests (Connector Acceptance Tests)
  • /build-connector-images - Builds and publishes a pre-release docker image for the modified connector(s).
  • JVM connectors:
    • /update-connector-cdk-version connector=<CONNECTOR_NAME> - Updates the specified connector to the latest CDK version.
      Example: /update-connector-cdk-version connector=destination-bigquery
    • /bump-bulk-cdk-version type=patch changelog='foo' - Bump the Bulk CDK's version. type can be major/minor/patch.
  • Python connectors:
    • /poe connector source-example lock - Run the Poe lock task on the source-example connector, committing the results back to the branch.
    • /poe source example lock - Alias for /poe connector source-example lock.
    • /poe source example use-cdk-branch my/branch - Pin the source-example CDK reference to the branch name specified.
    • /poe source example use-cdk-latest - Update the source-example CDK dependency to the latest available version.

📝 Edit this welcome message.

Copy link
Contributor

github-actions bot commented Oct 9, 2025

source-google-ads Connector Test Results

66 tests   62 ✅  4m 11s ⏱️
 2 suites   4 💤
 2 files     0 ❌

Results for commit 6ccbd79.

♻️ This comment has been updated with latest results.

Copy link
Contributor Author

/bump-version

Copy link
Contributor

github-actions bot commented Oct 9, 2025

Deploy preview for airbyte-docs ready!

✅ Preview
https://airbyte-docs-a3tw8hj7o-airbyte-growth.vercel.app

Built with commit 6ccbd79.
This pull request is being automatically deployed with vercel-action

@DanyloGL DanyloGL moved this from New PRs to Shield Team: In Review in 🧑‍🏭 Community Pull Requests Oct 13, 2025
@DanyloGL DanyloGL moved this from Shield Team: In Review to Waiting Eng Team in 🧑‍🏭 Community Pull Requests Oct 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Waiting Eng Team

Development

Successfully merging this pull request may close these issues.

1 participant