Skip to content

fix(proto): accept provider field in IacProviderConfig (v0.9.0 regression)#59

Merged
intel352 merged 1 commit intomainfrom
fix/iac-provider-config-provider-field
May 3, 2026
Merged

fix(proto): accept provider field in IacProviderConfig (v0.9.0 regression)#59
intel352 merged 1 commit intomainfrom
fix/iac-provider-config-provider-field

Conversation

@intel352
Copy link
Copy Markdown
Contributor

@intel352 intel352 commented May 3, 2026

Summary

v0.9.0 strict-contracts (PR #41) didn't declare a provider field on IacProviderConfig. wfctl uses protojson UnmarshalOptions{DiscardUnknown: false} (plugin/external/convert.go:65) which rejects unknown fields, so configs carrying the canonical provider: digitalocean discriminator (BMW, core-dump, every existing iac.provider config) fail typed-config marshal.

The error surfaces as protobuf error because wfctl's cmd/wfctl/main.go:206-209 unwraps to the bottom-most error (google.golang.org/protobuf/internal/errors.Error = "protobuf error"), stripping all wrapping context. This required hours of source-diving to identify.

Real-world impact

wfctl infra apply against any v0.9.0+ DO plugin with provider: in the config fails at:

error: protobuf error

Removing provider: breaks bootstrap differently:

error: no iac.provider module found in config — add an iac.provider module to bootstrap remote state backends (backend="spaces")

Both failures observed in core-dump deploy runs 25276880916 (with provider:) and 25277359916 (without).

Fix

Add string provider = 5; to IacProviderConfig proto. The plugin itself doesn't use the field — manifest.iacProvider.name = digitalocean is the source of truth for provider identity — but the proto must accept it so strict-contracts unmarshal doesn't reject configs with the canonical discriminator.

Regenerated proto/digitalocean.pb.go via protoc --go_out=..

Bumps to v0.9.1.

Suggested follow-ups (separate PRs / repos)

  1. wfctl error display: cmd/wfctl/main.go:206-209 unwraps to root, hiding the proto field name. Print the full chain or just the immediate wrapper.
  2. wfctl strict-contracts: define a list of "wfctl-meta" fields (provider, etc.) that get stripped from typed-config payloads before marshal, so plugin protos don't have to enumerate them.

Test plan

  • CI green
  • Tag v0.9.1 → goreleaser publishes
  • Registry bump to v0.9.1
  • core-dump deploy succeeds past plugin-init

🤖 Generated with Claude Code

…ession)

wfctl bootstrap uses `provider: digitalocean` as the discriminator to
identify which iac.provider module owns a given backend (e.g.
`backend: spaces` for IaC state). v0.9.0's strict-contracts proto (PR
#41) didn't declare `provider`, so configs carrying the canonical
discriminator (BMW, core-dump, every existing iac.provider config)
failed typed-config marshal with `protobuf error` because wfctl uses
`protojson UnmarshalOptions{DiscardUnknown: false}` (workflow
plugin/external/convert.go:65) which rejects unknown fields.

The plugin itself doesn't use this field — manifest.iacProvider.name =
digitalocean is the source of truth for provider identity — but the
proto must accept it so strict-contracts unmarshal doesn't reject the
config.

Surfaced by core-dump's first deploy attempt against v0.9.0 (run
25277359916: `error: no iac.provider module found in config — add an
iac.provider module to bootstrap remote state backends
(backend="spaces")` after temporarily removing `provider:` to bypass
the protobuf-error rejection).

Bumps to v0.9.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 3, 2026 11:07
Copy link
Copy Markdown

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

Fixes a v0.9.0 strict-contract regression where wfctl rejects IaC provider configs containing the canonical provider: digitalocean discriminator due to an undeclared proto field.

Changes:

  • Adds provider to IacProviderConfig in proto/digitalocean.proto to allow strict protojson unmarshalling.
  • Regenerates proto/digitalocean.pb.go to include the new field accessor and descriptor updates.
  • Documents the fix in CHANGELOG.md under Unreleased.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
proto/digitalocean.proto Declares provider field on IacProviderConfig to accept wfctl’s discriminator field under strict contracts.
proto/digitalocean.pb.go Regenerated Go bindings reflecting the new proto field.
CHANGELOG.md Adds an Unreleased entry describing the regression and fix.

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

Comment thread proto/digitalocean.pb.go
Comment on lines 1 to 5
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v3.21.12
// protoc v7.34.1
// source: proto/digitalocean.proto
Comment thread proto/digitalocean.proto
Comment on lines +25 to +35
// provider is the wfctl bootstrap discriminator (e.g. "digitalocean")
// used to identify which iac.provider module owns a given backend
// (per cmd/wfctl/infra_bootstrap.go's lookup for backend="spaces" etc.).
// The plugin itself does not need this field — manifest.iacProvider.name
// already declares ownership — but the strict-contracts proto must
// accept it because protojson UnmarshalOptions{DiscardUnknown: false}
// (workflow plugin/external/convert.go:65) errors on unknown fields.
// Without this declaration, configs with `provider: digitalocean`
// (the canonical pattern across BMW, core-dump, etc.) fail v0.9.0+
// strict-contract typed-config marshal.
string provider = 5;
Comment thread CHANGELOG.md
Comment on lines +15 to +19
the bottom-most error, hiding the field name). Added `string provider
= 5` to the proto; the field is accepted but ignored by the plugin
itself (manifest.iacProvider.name = digitalocean is the source of
truth for provider identity). Surfaced by core-dump's first deploy
attempt against v0.9.0.
@intel352 intel352 merged commit 30524f8 into main May 3, 2026
8 checks passed
@intel352 intel352 deleted the fix/iac-provider-config-provider-field branch May 3, 2026 11:10
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