Repository navigation
fix(cloud): raise AirbyteCloudError on malformed skill docs responses - #1367
Aaron ("AJ") Steers (aaronsteers) wants to merge 3 commits into
Conversation
Co-Authored-By: AJ Steers <aj@airbyte.io>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
👋 Greetings, Airbyte Team Member!Here are some helpful tips and reminders for your convenience. 💡 Show Tips and TricksTesting This PyAirbyte VersionYou can test this version of PyAirbyte using the following: # Run PyAirbyte CLI from this branch:
uvx --from 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1791854828-malformed-skill-docs' pyairbyte --help
# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1791854828-malformed-skill-docs'PR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
📚 Show Repo GuidanceHelpful ResourcesCommunity SupportQuestions? Join the #pyairbyte channel in our Slack workspace. |
There was a problem hiding this comment.
🟡 Changes recommended
Validation diagnostics can expose malformed Cloud response content through agent-facing warnings.
1 open finding
What changed in this PR
Validates Cloud skill-doc responses at the API boundary so malformed payloads become recoverable Cloud errors.
Changes:
- Return typed
DirectAccessGuidanceobjects fromread_cloud_skill_docs. - Remove redundant downstream validation.
- Update mocks and add malformed-response coverage.
| File | Description |
|---|---|
airbyte/_direct_connectors/api_util.py |
Adds response validation and error wrapping. |
airbyte/cloud/connectors.py |
Uses the typed response directly. |
airbyte/cloud/workspaces.py |
Removes redundant validation. |
tests/unit_tests/test_cloud_credentials.py |
Tests malformed response handling. |
tests/unit_tests/test_cloud_describe.py |
Updates guidance mocks to typed models. |
tests/unit_tests/test_cloud_guidance.py |
Updates workspace guidance mocks. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-Authored-By: AJ Steers <aj@airbyte.io>
Code Coverage OverviewLanguages: Python Python / code-coverage/pytest-no-credsThe overall line coverage in commit 2157bf3 in the Show a line coverage summary of the most impacted files.
Python / code-coverage/pytestThe overall line coverage in commit 2157bf3 in the Show a line coverage summary of the most impacted files.
Python / code-coverage/pytest-unitThe overall line coverage in commit 2157bf3 in the Show a line coverage summary of the most covered files.
Updated |
| raise AirbyteCloudError( | ||
| message="Malformed Airbyte Cloud skill docs response.", | ||
| context={ | ||
| "path": path, | ||
| "skill_id": skill_id, | ||
| "errors": ex.errors(include_url=False, include_input=False), | ||
| }, | ||
| ) from ex |
There was a problem hiding this comment.
No. Too generic. Define a new exception for this.
There was a problem hiding this comment.
Also - why does this even exist? Does it help anything?
There was a problem hiding this comment.
Added AirbyteMalformedSkillDocsError(AirbyteCloudError) with a skill_id field in 2157bf3.
On "does it help": only in a hypothetical case. If Cloud ever returns a skills/docs body without the required metadata, then on RC today DirectAccessGuidance.model_validate raises a raw pydantic ValidationError, which describe_cloud_connector doesn't catch, so the whole describe fails. With this PR, describe returns a warning instead. We haven't seen Cloud return a payload like that; the only source for the scenario is #1240. The cost: it turns a server-contract break into a soft warning, and it adds a new public exception. No further changes until you decide.
…cs responses Co-Authored-By: AJ Steers <aj@airbyte.io>
|
Closing. Won't do, pending repro or in-the-wild reports. We haven't seen Cloud return a malformed skills/docs payload, to my knowledge, and if it ever does, we'd first inspect as a server contract bug that should fail loudly instead of turning into a soft warning. Declining adding a new public exception for what appears as of now as only a hypothetical case. Note: I couldn't get this PR to pass the "foot gun" test - which is to ask: is this more likely to help or hurt? Since chance or helping hurting is 60/40% and I don't know which is more likely, I'm electing to close until I have a report of an issue I can work with. |

Overview
👉 TL;DR: A badly shaped connector-docs response from Airbyte Cloud now raises the same Cloud error type as other Cloud failures, so describing a connector reports a warning instead of failing outright.
Specifically,
read_cloud_skill_docsnow validates the response asDirectAccessGuidanceand wraps a pydanticValidationErrorinAirbyteCloudError("Malformed Airbyte Cloud skill docs response."), matching howget_cloud_connector_enablementhandles a malformed enablement response.Replaces the remaining malformed-docs part of #1240.
Changes
airbyte/_direct_connectors/api_util.py::read_cloud_skill_docs: returnsDirectAccessGuidanceinstead ofdict[str, Any]; a validation failure raisesAirbyteCloudErrorwithpath,skill_id, and the pydanticerrorsincontext.airbyte/cloud/connectors.py(_context_layer_inspect,read_agent_skill_docs,get_direct_access_guidance) andairbyte/cloud/workspaces.py::get_agent_skill_docs: drop the now-redundantDirectAccessGuidance.model_validate(...)wrappers.test_read_cloud_skill_docs_rejects_malformed_response; existing fakes ofread_cloud_skill_docsintest_cloud_describe.py/test_cloud_guidance.pyreturnDirectAccessGuidanceto match the new contract.Before, a malformed docs payload raised a raw
ValidationErrorfrom the call sites above, which_describe_cloud_connectordoes not catch (it catchesAirbyteCloudError/PyAirbyteError/RequestException), so one bad optional payload failed the whole describe call. Now the non-403/404AirbyteCloudErrorfollows the existing paths: describe records a warning,_context_layer_inspectstill re-raises it (not treated as "not enabled").Review Spotlight
Reviewers with limited time, please review first:
api_util.py#L348-L381: the new validation boundaryTest plan
pytest tests/unit_tests/test_cloud_describe.py test_cloud_credentials.py test_cloud_direct_execute.py test_cloud_guidance.py test_mcp_cloud.py test_cloud_api_util.py-> 660 passedruff check,ruff format,pyrefly check-> cleanLink to Devin session: https://app.devin.ai/sessions/ee9a2ac6748746439ad543c3b12bc37c
Open in Devin Desktop: https://app.devin.ai/desktop/session/ee9a2ac6748746439ad543c3b12bc37c?variant=devin
Requested by: Aaron ("AJ") Steers (@aaronsteers)