Skip to content

feat(config): emit ConduitError codes + configPath for pipeline validation#2529

Merged
devarismeroxa merged 3 commits into
mainfrom
feat/conduiterr-config-validation
Jul 5, 2026
Merged

feat(config): emit ConduitError codes + configPath for pipeline validation#2529
devarismeroxa merged 3 commits into
mainfrom
feat/conduiterr-config-validation

Conversation

@devarismeroxa

Copy link
Copy Markdown
Contributor

Structured-error rollout — the configPath step. Pipeline-config validation now attaches a machine-actionable code and a JSON-pointer to the offending field for every validation error.

Before: "plugin" is mandatory. After: code=config.field_required, configPath=/connectors/0/processors/0/id — an agent or UI knows exactly what to fix and where. This delivers the "failing config path" half of the machine-actionable-errors promise.

What changed

  • codes.go: registers config.field_required/field_invalid/field_too_long/id_duplicate + a fieldError helper.
  • validate.go: each check builds its JSON-pointer; validateProcessors takes a pathPrefix so nested connector processors get /connectors/i/processors/j/....
  • Backward-compatible: the original sentinels stay in the chain, so existing errors.Is checks and tests are untouched (they pass unchanged).

Codes flow through the boundary wired in #2527: ConduitError → ToStatus → google.rpc.ErrorInfo with reason + configPath, on the wire.

Tests

TestValidate_ConfigPathAndCode asserts the code + exact path for pipeline/connector/nested-processor fields; the full provisioning suite passes unchanged.

Tier 2 (additive, backward-compatible). Advances #2451 and the v0.16 structured-error work.

🤖 Generated with Claude Code

devarismeroxa and others added 3 commits July 5, 2026 14:35
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>
…ation

Structured-error rollout: pipeline-config validation now attaches a
machine-actionable code and a JSON-pointer configPath to the offending field for
every validation error — so an API/MCP/UI consumer gets exactly what is wrong and
where (e.g. code=config.field_required, configPath=/connectors/0/processors/0/id),
not just a prose string. This delivers the "failing config path" half of the
machine-actionable-errors promise.

- codes.go registers config.field_required/field_invalid/field_too_long/
  id_duplicate and a fieldError helper.
- Validate/validateConnectors/validateProcessors build the JSON-pointer per field
  (validateProcessors takes a pathPrefix so nested connector processors get
  /connectors/i/processors/j/...).
- The original sentinels (ErrMandatoryField, ErrInvalidField, ErrDuplicateID,
  pipeline/connector over-limit errors) stay in the chain — existing errors.Is
  checks and tests are unaffected.

Codes flow through the API boundary wired earlier: ConduitError -> ToStatus ->
google.rpc.ErrorInfo with reason + configPath, on the wire.

Design: docs/design-documents/20260705-conduit-error-and-structured-output.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@devarismeroxa devarismeroxa requested a review from a team as a code owner July 5, 2026 22:38
@devarismeroxa devarismeroxa merged commit 0494430 into main Jul 5, 2026
5 checks passed
@devarismeroxa devarismeroxa deleted the feat/conduiterr-config-validation branch July 5, 2026 22:44
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.

1 participant