Skip to content

fix: Skip local validation when deploying connectors to Cloud via MCP#851

Merged
Aaron ("AJ") Steers (aaronsteers) merged 9 commits intomainfrom
devin/1762289840-fix-mcp-cloud-destination-install
Nov 5, 2025
Merged

fix: Skip local validation when deploying connectors to Cloud via MCP#851
Aaron ("AJ") Steers (aaronsteers) merged 9 commits intomainfrom
devin/1762289840-fix-mcp-cloud-destination-install

Conversation

@aaronsteers
Copy link
Member

@aaronsteers Aaron ("AJ") Steers (aaronsteers) commented Nov 4, 2025

fix: Skip local validation when deploying connectors to Cloud via MCP

Summary

Fixes #850 - MCP was trying to install connectors locally before deploying them to Cloud, which failed when Python/Docker wasn't available or the connector couldn't be installed.

The root cause: deploy_source_to_cloud() and deploy_destination_to_cloud() were calling .config_spec which triggers local connector execution via _execute(), requiring the connector to be installed locally.

The fix skips local validation entirely by:

  1. Passing config_spec_jsonschema=None to resolve_config() - skips hardcoded secrets detection
  2. Passing validate=False to set_config() - skips config schema validation

Since CloudWorkspace.deploy_source/destination() only accesses .name and ._hydrated_config, no local execution is needed. All validation now happens server-side via the Cloud API.

Review & Testing Checklist for Human

  • End-to-end test: Deploy a source and destination to Cloud via MCP in an environment without Python/Docker to verify the original issue is resolved
  • Validation fallback: Confirm that invalid configs are properly caught and reported by Cloud API validation (since local validation is now skipped)
  • Edge case review: Check if any other MCP functions might have similar local execution requirements that weren't addressed

Test Plan

  1. Set up MCP environment without local Python/Docker or where connectors can't be installed
  2. Use the deploy_source_to_cloud and deploy_destination_to_cloud MCP tools to deploy connectors
  3. Verify deployment succeeds without installation errors
  4. Try with both valid and invalid configs to confirm Cloud validation works

Notes

  • This PR intentionally shifts validation from local (client-side) to Cloud (server-side)
  • The install_if_missing=False parameter was already present but insufficient because .config_spec still triggered local execution
  • Alternative approaches considered but rejected: NoOp executor (would require broader changes), propagating install_if_missing through all executors (too broad for this fix)

Link to Devin run: https://app.devin.ai/sessions/d1818e9eff6f4b0ebd7b0cb0b9b85865
Requested by: AJ Steers (Aaron ("AJ") Steers (@aaronsteers))

Summary by CodeRabbit

  • New Features

    • Validate connector configs against registry specs.
    • "No-executor" mode to operate/inspect connectors without installing them.
    • Registry-based connector spec fetching utility.
  • Bug Fixes

    • Cloud deployments now validate configs against registry specs to catch invalid configs earlier.
  • Changes

    • Connector listings now default to showing Docker-installable connectors.
  • Tests

    • Added integration tests for registry spec fetching and config validation.

- Pass config_spec_jsonschema=None to resolve_config() to skip hardcoded secrets validation
- Call set_config(validate=False) to avoid triggering local connector execution
- This prevents installation errors when deploying to Cloud without local Python/Docker

Fixes #850

Co-Authored-By: AJ Steers <aj@airbyte.io>
@devin-ai-integration
Copy link
Contributor

Original prompt from AJ Steers
SYSTEM:
=== BEGIN THREAD HISTORY (in #dev-coral-mcp) ===
AJ Steers (U05AKF1BCC9): <@U09J01V4QPL> - I logged this issue to cover the bug you reported in DM: <https://github.com/airbytehq/PyAirbyte/issues/850>

#850 :bug: Bug: Coral MCP tries to install connectors before deploying a coral cloud destination

AJ Steers (U05AKF1BCC9): @Devin - Please take a look at the above and see if you can fix the issue.
=== END THREAD HISTORY ===

Thread URL: https://airbytehq-team.slack.com/archives/C065V6XFWNQ/p1762289692063649?thread_ts=1762289692.063649&cid=C065V6XFWNQ

The latest message is the one right above that tagged you.

@devin-ai-integration
Copy link
Contributor

🤖 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

github-actions bot commented Nov 4, 2025

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

Testing This PyAirbyte Version

You 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/1762289840-fix-mcp-cloud-destination-install' pyairbyte --help

# Install PyAirbyte from this branch for development:
pip install 'git+https://github.com/airbytehq/PyAirbyte.git@devin/1762289840-fix-mcp-cloud-destination-install'

Helpful Resources

PR Slash Commands

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

  • /fix-pr - Fixes most formatting and linting issues
  • /poetry-lock - Updates poetry.lock file
  • /test-pr - Runs tests with the updated PyAirbyte

Community Support

Questions? Join the #pyairbyte channel in our Slack workspace.

📝 Edit this welcome message.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 4, 2025

Warning

Rate limit exceeded

devin-ai-integration[bot] has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 12 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 03117ee and f6178db.

📒 Files selected for processing (2)
  • airbyte/_executors/util.py (5 hunks)
  • tests/integration_tests/test_registry_spec.py (1 hunks)
📝 Walkthrough

Walkthrough

Add a NoOp executor path and registry-spec utilities; get_source/get_destination gain a no_executor flag; cloud deploys request server-side validation via set_config(..., validate=True); connector listing defaults to Docker-installable connectors.

Changes

Cohort / File(s) Summary
Cloud ops changes
airbyte/mcp/cloud_ops.py
deploy_source_to_cloud / deploy_destination_to_cloud now create executors with no_executor=True and call set_config(..., validate=True).
Connector registry default
airbyte/mcp/connector_registry.py
Default connector listing now calls get_available_connectors(install_type=InstallType.DOCKER); InstallType imported.
No-op executor
airbyte/_executors/noop.py
New NoOpExecutor class: no-op install/uninstall, handles spec by fetching registry spec (cloud then OSS), caches spec, yields SPEC message, raises informative error for unsupported commands.
Registry spec utilities
airbyte/_util/registry_spec.py
New functions get_connector_spec_from_registry(...) and validate_connector_config_from_registry(...) to fetch connector spec from registry (cloud/oss) and validate configs via jsonschema with timeouts and error handling.
Destination helper
airbyte/destinations/util.py
get_destination(...) adds no_executor: bool = False and delegates executor creation to get_connector_executor(..., no_executor=no_executor).
Source helper
airbyte/sources/util.py
get_source(...) adds no_executor: bool = False, obtains executor via get_connector_executor(..., no_executor=no_executor) and passes it into Source.
Executor utility
airbyte/_executors/util.py
get_connector_executor(...) adds no_executor: bool = False; when true, locally imports and returns a NoOpExecutor (after metadata retrieval), bypassing install/selection logic.
Integration tests
tests/integration_tests/test_registry_spec.py
New integration tests for registry-spec helpers: fetching spec and validating configs across connector/platform parameterizations.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant SourcesUtil as get_source()
  participant ExecUtil as get_connector_executor()
  participant Registry as ConnectorRegistry
  participant NoOp as NoOpExecutor

  Caller->>SourcesUtil: get_source(name, version, no_executor=True)
  SourcesUtil->>ExecUtil: get_connector_executor(name, version, no_executor=True)
  ExecUtil->>Registry: get_connector_metadata(name)
  Registry-->>ExecUtil: metadata
  ExecUtil->>NoOp: instantiate NoOpExecutor(name, metadata, target_version)
  NoOp-->>ExecUtil: executor
  ExecUtil-->>SourcesUtil: executor
  SourcesUtil-->>Caller: Source(executor=NoOp)
Loading
sequenceDiagram
  participant User
  participant CloudOps
  participant Registry
  participant CloudAPI

  User->>CloudOps: deploy_source_to_cloud(name, config)
  CloudOps->>Registry: get_connector_metadata(name)
  Registry-->>CloudOps: metadata
  CloudOps->>CloudAPI: set_config(config, validate=true, executor_noop=true)
  CloudAPI-->>CloudOps: deploy result
  CloudOps-->>User: status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review NoOpExecutor behavior, caching, and emitted SPEC message (airbyte/_executors/noop.py).
  • Verify registry-spec fetching, timeouts, error handling, and jsonschema usage (airbyte/_util/registry_spec.py).
  • Confirm no_executor early-return in get_connector_executor preserves backward compatibility and avoids import cycles (airbyte/_executors/util.py).
  • Check updated get_source/get_destination signatures and downstream callers for compatibility.
  • Should we add focused unit tests for NoOpExecutor flows (spec fetch failure, cached spec, and unsupported commands) to prevent regressions, wdyt?

Possibly related PRs

Suggested reviewers

  • ChristoGrab

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main change: preventing local validation during Cloud deployment by skipping executor installation.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

PyTest Results (Fast Tests Only, No Creds)

312 tests  +8   312 ✅ +8   5m 59s ⏱️ +18s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit f6178db. ± Comparison against base commit cbb0717.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b0844f and 6634835.

📒 Files selected for processing (1)
  • airbyte/mcp/connector_registry.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
airbyte/mcp/connector_registry.py (1)
airbyte/sources/registry.py (1)
  • get_available_connectors (225-281)
🪛 GitHub Actions: Run Linters
airbyte/mcp/connector_registry.py

[error] 74-74: Undefined name 'InstalledType' (F821) in type annotation. Referenced as InstalledType.DOCKER.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.10, Windows)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.11, Windows)
  • GitHub Check: Pytest (No Creds)
  • GitHub Check: Pytest (Fast)
🔇 Additional comments (1)
airbyte/mcp/connector_registry.py (1)

73-74: Verify: Should we list all connectors regardless of local Docker availability?

This changes the default behavior from environment-aware filtering to always returning all Docker connectors. Looking at the get_available_connectors() implementation, when install_type=None, it intelligently checks whether Docker is installed and filters accordingly. With install_type=InstallType.DOCKER, it always returns all connectors.

In environments where Docker is not available, this will now list connectors that cannot actually be installed or run locally. Is this intentional for Cloud-focused workflows, or should we preserve the environment-aware behavior? Wdyt?

If the intent is to make this Cloud-focused (where Docker is always available), consider updating the docstring to clarify that the list represents connectors available for Cloud deployment rather than local execution.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
devin-ai-integration bot and others added 2 commits November 4, 2025 21:56
…al installation

- Implement NoOpExecutor that fetches connector specs from registry
- Add helper functions get_connector_spec_from_registry() and validate_connector_config_from_registry()
- Add no_executor parameter to get_source() and get_destination()
- Update MCP cloud deploy tools to use NoOpExecutor by default
- Enables pre-validation of connector configs without Docker/Python installation
- Fixes connector_registry.py typo: InstalledType -> InstallType

Closes #850

Co-Authored-By: AJ Steers <aj@airbyte.io>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
airbyte/mcp/connector_registry.py (1)

17-17: Import fix looks good!

This correctly addresses the undefined name error flagged in the previous review.

🧹 Nitpick comments (4)
airbyte/sources/util.py (1)

121-140: Same concerns as destinations/util.py apply here.

The conditional logic mirrors the destination implementation (lines 79-97 in airbyte/destinations/util.py). The same verification request about None metadata handling and the refactoring suggestion to extract common logic apply here as well.

airbyte/_util/registry_spec.py (2)

19-19: Consider making the registry URL configurable.

The spec URL is currently hardcoded to connectors.airbyte.com. I noticed in the error messages from airbyte/_executors/util.py there's mention of a _REGISTRY_ENV_VAR for custom registries. Should this URL template also respect custom registry configuration for consistency? Wdyt?


27-27: Consider documenting the platform parameter more thoroughly.

The platform parameter accepts "cloud" or "oss", but there's no explanation of when to use which. I see that NoOpExecutor tries "cloud" first then falls back to "oss" (lines 78-88 in airbyte/_executors/noop.py). It might help users to document:

  • What's the difference between cloud and OSS specs?
  • When should callers prefer one over the other?

Wdyt about expanding the docstring?

airbyte/_executors/noop.py (1)

76-88: Consider making platform preference configurable.

The executor currently tries "cloud" first, then falls back to "oss". This makes sense for Cloud deployments, but some users might want to prefer OSS specs. Would it make sense to add an optional platform_preference parameter to the NoOpExecutor constructor that could be passed through from get_source()/get_destination()? This would be consistent with how registry_spec.py already accepts a platform parameter. Wdyt?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c4b87d and 012d174.

📒 Files selected for processing (6)
  • airbyte/_executors/noop.py (1 hunks)
  • airbyte/_util/registry_spec.py (1 hunks)
  • airbyte/destinations/util.py (4 hunks)
  • airbyte/mcp/cloud_ops.py (2 hunks)
  • airbyte/mcp/connector_registry.py (2 hunks)
  • airbyte/sources/util.py (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • airbyte/mcp/cloud_ops.py
🧰 Additional context used
🧬 Code graph analysis (5)
airbyte/destinations/util.py (3)
airbyte/_executors/noop.py (1)
  • NoOpExecutor (26-131)
airbyte/_executors/util.py (1)
  • get_connector_executor (158-371)
airbyte/sources/registry.py (1)
  • get_connector_metadata (195-222)
airbyte/sources/util.py (3)
airbyte/_executors/noop.py (1)
  • NoOpExecutor (26-131)
airbyte/_executors/util.py (1)
  • get_connector_executor (158-371)
airbyte/sources/registry.py (1)
  • get_connector_metadata (195-222)
airbyte/_executors/noop.py (4)
airbyte/_executors/base.py (1)
  • Executor (159-248)
airbyte/_util/registry_spec.py (1)
  • get_connector_spec_from_registry (23-98)
airbyte/sources/registry.py (1)
  • ConnectorMetadata (58-89)
airbyte/exceptions.py (1)
  • AirbyteConnectorExecutableNotFoundError (340-341)
airbyte/mcp/connector_registry.py (1)
airbyte/sources/registry.py (2)
  • InstallType (41-47)
  • get_available_connectors (225-281)
airbyte/_util/registry_spec.py (3)
airbyte/sources/registry.py (1)
  • get_connector_metadata (195-222)
airbyte/version.py (1)
  • get_version (12-14)
airbyte/exceptions.py (1)
  • AirbyteConnectorNotRegisteredError (288-297)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (Fast)
  • GitHub Check: Pytest (All, Python 3.11, Windows)
  • GitHub Check: Pytest (All, Python 3.10, Windows)
  • GitHub Check: Pytest (No Creds)
🔇 Additional comments (9)
airbyte/destinations/util.py (3)

11-14: Imports look good!

The new imports are necessary for the no_executor pathway and are properly used below.


36-36: Parameter addition looks good!

The no_executor parameter with a default of False maintains backward compatibility while enabling the new Cloud deployment pathway.


79-97: Code duplication in executor creation can be reduced with a helper function.

The None metadata handling is actually fine—get_connector_spec_from_registry() explicitly handles version=None by using the latest available version from metadata. However, you've got identical executor creation logic in both get_destination() and get_source() (lines 79-97 in destinations/util.py and lines 121-140 in sources/util.py).

Would extracting a _create_noop_executor() helper function make sense here? It could accept name and version parameters and return the executor, reducing duplication and making future updates easier to maintain consistently across both functions. Wdyt?

airbyte/sources/util.py (1)

10-14: Consistent implementation with destinations!

The imports and structure mirror the changes in airbyte/destinations/util.py, which is great for consistency.

airbyte/_util/registry_spec.py (2)

23-98: Excellent error handling!

The function gracefully handles multiple failure scenarios (timeouts, request failures, missing specs) by logging warnings and returning None. This allows callers like NoOpExecutor to decide how to handle unavailable specs without crashing. The logging provides good debugging context too.


101-141: Clean validation implementation!

The function properly reuses get_connector_spec_from_registry and provides clear return values. The tuple return type (bool, str | None) makes it easy for callers to check validity and get error details when needed.

airbyte/_executors/noop.py (3)

26-53: Well-designed class structure!

The NoOpExecutor properly extends the Executor base class and maintains a cached spec to minimize registry requests. The docstring clearly explains the use case and limitations.


90-96: Good graceful degradation!

When the spec can't be fetched, logging a warning and yielding nothing (instead of crashing) allows Cloud deployments to proceed even if the registry is temporarily unavailable. The warning provides debugging context without blocking the deployment flow.


120-131: No-op installation methods are appropriate!

Since NoOpExecutor doesn't require local installation (the whole point!), these no-op implementations of ensure_installation(), install(), and uninstall() are exactly right. The docstrings clearly explain why they're no-ops.

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

PyTest Results (Full)

373 tests  ±0   357 ✅ +1   27m 10s ⏱️ + 1m 40s
  1 suites ±0    16 💤 ±0 
  1 files   ±0     0 ❌  - 1 

Results for commit 012d174. ± Comparison against base commit cbb0717.

devin-ai-integration bot and others added 2 commits November 4, 2025 23:57
…d tests

- Refactored get_connector_executor() to handle no_executor parameter directly
- Removed NoOpExecutor branching logic from get_source() and get_destination()
- Both helpers now pass no_executor through to get_connector_executor()
- Fixed NoOpExecutor error guidance to reference correct parameter (no_executor)
- Added integration tests for registry_spec.py helper functions
- Uses local import in get_connector_executor() to avoid import cycles

Addresses PR feedback from @aaronsteers on PR #851

Co-Authored-By: AJ Steers <aj@airbyte.io>
- Changed invalid test case from using unknown fields to type/boundary violations
- Added test for type violation: count as string instead of integer
- Added test for boundary violation: count = 0 when minimum is 1
- These test actual JSON schema validation rather than relying on required fields

Co-Authored-By: AJ Steers <aj@airbyte.io>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
airbyte/_executors/noop.py (1)

120-123: Remove the unnecessary pass statement.

As noted in the previous review, line 123's pass is redundant since line 122 (_ = auto_fix # Unused) already keeps the method body non-empty. Wdyt about removing it for consistency?

Apply this diff:

     def ensure_installation(self, *, auto_fix: bool = True) -> None:
         """No-op: NoOpExecutor doesn't require installation."""
         _ = auto_fix  # Unused
-        pass
🧹 Nitpick comments (1)
airbyte/_executors/noop.py (1)

76-107: Solid spec command implementation with good fallback logic.

The cloud-first fallback to OSS is a smart approach, and the caching prevents redundant fetches. The SPEC message structure matches the expected Airbyte protocol format.

Minor nitpick: Line 95 uses yield from [] which is equivalent to just return on line 96. Wdyt about simplifying to just the return statement?

If you'd like to simplify, apply this diff:

                 if spec is None:
                     logger.warning(
                         f"Could not fetch spec for connector '{self.name}' from registry. "
                         f"Pre-validation will not be available."
                     )
-                    yield from []
                     return
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 012d174 and 1099532.

📒 Files selected for processing (5)
  • airbyte/_executors/noop.py (1 hunks)
  • airbyte/_executors/util.py (1 hunks)
  • airbyte/destinations/util.py (2 hunks)
  • airbyte/sources/util.py (2 hunks)
  • tests/integration_tests/test_registry_spec.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-08T15:34:31.026Z
Learnt from: aaronsteers
Repo: airbytehq/PyAirbyte PR: 347
File: tests/integration_tests/fixtures/registry.json:48-48
Timestamp: 2024-10-08T15:34:31.026Z
Learning: Test fixtures in the PyAirbyte project do not need to align with real Docker repositories.

Applied to files:

  • tests/integration_tests/test_registry_spec.py
🧬 Code graph analysis (5)
airbyte/destinations/util.py (2)
airbyte/_executors/util.py (1)
  • get_connector_executor (158-384)
airbyte/destinations/base.py (1)
  • Destination (38-300)
airbyte/sources/util.py (2)
airbyte/_executors/util.py (1)
  • get_connector_executor (158-384)
airbyte/sources/base.py (1)
  • Source (67-972)
airbyte/_executors/noop.py (5)
airbyte/_executors/base.py (1)
  • Executor (159-248)
airbyte/_util/registry_spec.py (1)
  • get_connector_spec_from_registry (23-98)
airbyte/_message_iterators.py (1)
  • AirbyteMessageIterator (61-207)
airbyte/sources/registry.py (1)
  • ConnectorMetadata (58-89)
airbyte/exceptions.py (1)
  • AirbyteConnectorExecutableNotFoundError (340-341)
airbyte/_executors/util.py (3)
airbyte/_executors/base.py (1)
  • Executor (159-248)
airbyte/_executors/noop.py (1)
  • NoOpExecutor (26-131)
airbyte/sources/registry.py (1)
  • get_connector_metadata (195-222)
tests/integration_tests/test_registry_spec.py (1)
airbyte/_util/registry_spec.py (2)
  • get_connector_spec_from_registry (23-98)
  • validate_connector_config_from_registry (101-141)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Pytest (Fast)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.11, Windows)
  • GitHub Check: Pytest (All, Python 3.10, Windows)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (No Creds)
🔇 Additional comments (7)
tests/integration_tests/test_registry_spec.py (2)

14-32: LGTM! Clean integration test for registry spec fetching.

The parameterization covers relevant connector types and platforms, and the assertions appropriately verify the basic spec structure.


35-74: Verify that the invalid config case reliably triggers validation errors.

This is an integration test that fetches live specs from Airbyte's registry. The concern remains valid: {"invalid_field": "value"} will only fail validation if source-faker's spec explicitly sets "additionalProperties": false. Since JSON Schema defaults to allowing additional properties, this test might unexpectedly pass if the spec permits them.

Rather than relying on an unexpected field, wdyt about using a more definitive invalid config—one that violates the schema itself? For example:

  • Providing a wrong type: {"count": "not-a-number"} instead of an integer
  • Missing a required field (if one exists)

This would make the test resilient regardless of the spec's additionalProperties setting. Would that be worth exploring?

airbyte/destinations/util.py (1)

34-95: LGTM! Clean implementation of no_executor parameter.

The changes appropriately delegate executor creation to get_connector_executor with the no_executor flag, addressing the previous review feedback. The docstring clearly explains the use case for this parameter.

airbyte/sources/util.py (1)

62-139: LGTM! Consistent implementation with destinations.

The changes mirror the pattern in destinations/util.py and properly delegate executor creation to get_connector_executor, addressing the previous review feedback. The implementation is clean and well-documented.

airbyte/_executors/noop.py (2)

40-61: LGTM! Clean initialization and placeholder CLI.

The constructor properly initializes the spec cache, and the _cli placeholder with its explanatory comment is appropriate given that execute() is overridden.


109-118: LGTM! Error handling with helpful guidance.

The error message correctly references no_executor=True and provides clear guidance for users who attempt unsupported operations. This addresses the previous review comment about the parameter reference.

airbyte/_executors/util.py (1)

176-186: Add error handling to the no_executor path for consistency with the main flow

Good catch! The code shows an inconsistency: the no_executor path (line 181) calls get_connector_metadata(name) without error handling, while the main execution path (lines 230-235) wraps the same call in a try-except block to handle AirbyteConnectorNotRegisteredError.

If a non-existent connector is requested with no_executor=True, the exception will propagate uncaught, whereas in the normal path it's caught, logged, and re-raised with context. For consistency and better error diagnostics, should we add similar error handling to the no_executor block? This would ensure all code paths handle registry failures uniformly, wdyt?

devin-ai-integration bot and others added 2 commits November 5, 2025 00:16
…stall method

- Moved NoOpExecutor import to top of util.py (no import cycles detected)
- Included no_executor in install_method_count validation
- Moved no_executor handling to be inline with other install methods
- Updated error message to include no_executor in the list
- Verified functionality works correctly with local tests

Addresses PR feedback from @aaronsteers

Co-Authored-By: AJ Steers <aj@airbyte.io>
- Added test cases that specify explicit version (6.2.0) instead of defaulting to latest
- Tests both OSS and Cloud platforms with versioned specs
- Addresses PR feedback from @aaronsteers

Co-Authored-By: AJ Steers <aj@airbyte.io>
@aaronsteers Aaron ("AJ") Steers (aaronsteers) merged commit d8fd0be into main Nov 5, 2025
19 of 21 checks passed
@aaronsteers Aaron ("AJ") Steers (aaronsteers) deleted the devin/1762289840-fix-mcp-cloud-destination-install branch November 5, 2025 00:37
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.

🐛 Bug: Coral MCP tries to install connectors before deploying a coral cloud destination

1 participant