feat(plugin): emit connector.plugin_not_found ConduitError code#2528
Merged
Conversation
Step 2 of the structured-error rollout: the ConduitError foundation now reaches the API. When an error returned to a gRPC/HTTP handler carries a *ConduitError (anywhere in its chain), status.go emits its gRPC category plus an additive google.rpc.ErrorInfo detail carrying the stable reason, configPath, suggestion, and fix — so an API/MCP/UI consumer gets a machine-actionable error. This is a single integration point (conduitErrorStatus, checked at the top of PipelineError/ConnectorError/ProcessorError/PluginError). It is purely additive: any error that is NOT a ConduitError falls through to the existing sentinel->code mapping, byte-for-byte unchanged (existing tests still pass). Boundaries get migrated to emit ConduitError codes incrementally from here. Tests: a wrapped ConduitError yields the right code + ErrorInfo detail (reason, configPath, suggestion); a sentinel error maps exactly as before. Design: docs/design-documents/20260705-conduit-error-and-structured-output.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Step 3 of the structured-error rollout — the first real error source migrated to a ConduitError code, exercising the API boundary wired in the previous step. When the builtin connector registry can't find a plugin (unknown name, or a known name with no matching version), it now returns a ConduitError with code `connector.plugin_not_found` and a suggested fix, instead of a bare sentinel / generic wrapped error. The `plugin.ErrPluginNotFound` sentinel remains in the chain, so existing `errors.Is` checks are unaffected (invariant noted at the site; existing tests unchanged). End to end: registry -> ConduitError(code, suggestion) -> orchestrator -> API (status.ConnectorError/PluginError) -> ToStatus -> a google.rpc.ErrorInfo detail carrying reason=connector.plugin_not_found + the suggestion, on the wire. Test augments TestRegistry_NewDispenser_PluginNotFound to assert both the sentinel Is-check AND the new code + suggestion. Design: docs/design-documents/20260705-conduit-error-and-structured-output.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5 tasks
devarismeroxa
added a commit
that referenced
this pull request
Jul 5, 2026
…2530) Step 4 of the structured-error rollout: two more error sources now emit ConduitError codes instead of bare sentinels, following the pattern from connector.plugin_not_found (#2528). - pipeline.ErrInstanceNotFound, raised in pipeline.Service.Get (the sole choke point — Update/Delete/AddConnector/etc. all call Get internally), now wraps with a new code pipeline.instance_not_found (codes.NotFound) and a suggestion to run `conduit pipelines list`. - connector.ErrInstanceNotFound, raised in connector.Service.Get (same choke-point property), wraps with connector.instance_not_found (codes.NotFound) and a suggestion to run `conduit connectors list`. Both sentinels remain in the error chain via conduiterr.Wrap, so existing errors.Is(err, ErrInstanceNotFound) checks throughout pkg/provisioning, pkg/orchestrator, and pkg/http/api/status are unaffected — verified by running those suites plus pkg/lifecycle(-poc). Tests augment TestService_GetInstanceNotFound in both packages to assert the sentinel Is-check AND the new code + non-empty Suggestion via conduiterr.Get. processor.ErrInstanceNotFound is a separate, un-migrated error source (pkg/processor/service.go) — left out of scope for this step to keep the blast radius tight; it's a natural next candidate. Design: docs/design-documents/20260705-conduit-error-and-structured-output.md Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
devarismeroxa
added a commit
that referenced
this pull request
Jul 6, 2026
…gin registries) (#2532) Finishes the not-found migrations begun in the connector-plugin (#2528) and pipeline/connector-instance (#2530) PRs: - processor.instance_not_found (CodeProcessorNotFound, pkg/processor/codes.go): Service.Get now wraps ErrInstanceNotFound with the code + a suggestion — the single choke point every processor method routes through. - processor.plugin_not_found (CodeProcessorPluginNotFound): the builtin and standalone processor registries now emit the code when a plugin/version is missing, mirroring the connector builtin registry from #2528. - connector.plugin_not_found: the standalone connector registry now emits the code too, completing the connector plugin-not-found set (builtin was #2528). All sites keep the original sentinel in the chain via conduiterr.Wrap (errors.Is(err, ErrInstanceNotFound) / plugin.ErrPluginNotFound unaffected; invariant noted at each site). Purely additive. Test: TestService_Get_Fail asserts both the sentinel Is-check and the new code + suggestion. Existing registry/service suites pass unchanged. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 3 of the structured-error rollout — the first real error source migrated to a
ConduitErrorcode, exercising the API boundary from #2527.When the builtin connector registry can't find a plugin (unknown name, or known name with no matching version), it now returns a
ConduitErrorwith codeconnector.plugin_not_foundand a suggested fix, instead of a bare sentinel. Theplugin.ErrPluginNotFoundsentinel stays in the chain, so existingerrors.Ischecks are unaffected (existing tests pass unchanged).End to end: registry →
ConduitError(code, suggestion)→ orchestrator → API (status.ConnectorError/PluginError) →ToStatus→ agoogle.rpc.ErrorInfodetail carryingreason=connector.plugin_not_found+ the suggestion, on the wire — the first genuine machine-actionable code an API/MCP/UI consumer sees.Test augmented to assert both the sentinel
Is-check and the new code + suggestion. Tier 2 (additive; backward-compatible). Advances #2451.🤖 Generated with Claude Code