Skip to content

fix(cdk): Handle TypeError in _literal_eval for nested set literals (AI-Triage PR)#936

Merged
sophiecuiy merged 2 commits intomainfrom
devin/1772779194-fix-literal-eval-typeerror
Mar 6, 2026
Merged

fix(cdk): Handle TypeError in _literal_eval for nested set literals (AI-Triage PR)#936
sophiecuiy merged 2 commits intomainfrom
devin/1772779194-fix-literal-eval-typeerror

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot commented Mar 6, 2026

Summary

Adds TypeError to the exception handler in JinjaInterpolation._literal_eval(). When ast.literal_eval() encounters a string resembling nested Python set literals (e.g. {{'web'}, {'discover'}}), it raises TypeError: unhashable type: 'set' because sets cannot contain other sets. The existing handler only caught ValueError and SyntaxError, so this TypeError propagated unhandled and crashed syncs.

This was reported for the source-google-search-console connector where AddFields transformations render record values via Jinja templates. When a record field value happens to look like a nested set literal, _literal_eval fails on the post-render parse step.

The fix returns the string as-is (matching the existing fallback behavior for other unparseable literals).

Resolves https://github.com/airbytehq/oncall/issues/11543:

Updates since last revision

  • Updated the misleading inline comment (# literal_eval is able to handle None# result may be None; on error we return it unchanged) per Copilot review. The old comment implied literal_eval handles None gracefully, but it actually raises TypeError on None input — which is now correctly caught.

Review & Testing Checklist for Human

  • Verify TypeError breadth is acceptable: This catches all TypeErrors from ast.literal_eval, not just the unhashable-set case. Confirm there's no scenario where a TypeError here should propagate rather than fall back to returning the raw string. (Note: literal_eval(None) also raises TypeError, meaning the old code had a latent crash path for None inputs too — catching it is the correct behavior.)
  • Confirm the test reproduces the real failure path: The test passes {{'web'}, {'discover'}} through the full interpolation.eval() flow, but verify this matches how AddFields invokes it at runtime (via InterpolatedString.evalJinjaInterpolation.eval_literal_eval).
  • Recommended test plan: Run a local sync of source-google-search-console with a site that returns searchType values like {'web'}, {'discover'} in the search_analytics streams, or manually invoke JinjaInterpolation.eval() with a config containing nested-set-like string values and confirm no crash.

Notes

  • The change is in airbyte_cdk (core CDK library), but is trivially safe — it only broadens a catch clause that already catches two other exception types in the same fallback pattern.
  • No breaking change: behavior is unchanged for all inputs that previously worked; only previously-crashing inputs now succeed.
  • Link to Devin session
  • Requested by: bot_apk

When ast.literal_eval() encounters a string like "{{'\''web'\''}, {'\''discover'\''}}"
that resembles nested Python set literals, it raises TypeError: unhashable
type: '\''set'\'' because sets cannot contain other sets. The existing except
clause only caught (ValueError, SyntaxError) but not TypeError.

This fix adds TypeError to the except clause so the string is returned
as-is, matching the existing behavior for other unparseable literals.

Resolves airbytehq/oncall#11543

Co-Authored-By: bot_apk <apk@cognition.ai>
@devin-ai-integration
Copy link
Copy Markdown
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

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 6, 2026

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

Testing This CDK Version

You can test this version of the CDK using the following:

# Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@devin/1772779194-fix-literal-eval-typeerror#egg=airbyte-python-cdk[dev]' --help

# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch devin/1772779194-fix-literal-eval-typeerror

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /autofix - Fixes most formatting and linting issues
  • /poetry-lock - Updates poetry.lock file
  • /test - Runs connector tests with the updated CDK
  • /prerelease - Triggers a prerelease publish with default arguments
  • /poe build - Regenerate git-committed build artifacts, such as the pydantic models which are generated from the manifest JSON schema in YAML.
  • /poe <command> - Runs any poe command in the CDK environment
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 6, 2026

PyTest Results (Fast)

3 891 tests  +1   3 879 ✅ +1   6m 52s ⏱️ -1s
    1 suites ±0      12 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 346cc58. ± Comparison against base commit 6136336.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 6, 2026

PyTest Results (Full)

3 894 tests  +1   3 882 ✅ +1   10m 34s ⏱️ +2s
    1 suites ±0      12 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 346cc58. ± Comparison against base commit 6136336.

♻️ This comment has been updated with latest results.

@sophiecuiy sophiecuiy marked this pull request as ready for review March 6, 2026 21:47
Copilot AI review requested due to automatic review settings March 6, 2026 21:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prevents unhandled exceptions during Jinja interpolation by treating TypeError from ast.literal_eval() as a non-fatal parse failure and falling back to returning the raw string, matching existing behavior for other unparseable literals. This addresses crashes triggered by rendered strings that resemble nested Python set literals.

Changes:

  • Broadened _literal_eval() exception handling to also catch TypeError from ast.literal_eval().
  • Added a unit test reproducing the nested-set-literal TypeError scenario through the public interpolation.eval() flow.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
airbyte_cdk/sources/declarative/interpolation/jinja.py Catch TypeError in _literal_eval() to prevent sync crashes and preserve fallback-to-string behavior.
unit_tests/sources/declarative/interpolation/test_jinja.py Add regression test ensuring nested set-literal-like strings don’t crash interpolation and are returned as-is.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-Authored-By: bot_apk <apk@cognition.ai>
@sophiecuiy sophiecuiy merged commit 171054f into main Mar 6, 2026
27 of 28 checks passed
@sophiecuiy sophiecuiy deleted the devin/1772779194-fix-literal-eval-typeerror branch March 6, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants