Skip to content

fix(agentcrd): strip server-managed metadata before ResumeAll re-apply - #790

Merged
OisinKyne merged 1 commit into
mainfrom
fix/agent-resume-strip-metadata
Jul 20, 2026
Merged

fix(agentcrd): strip server-managed metadata before ResumeAll re-apply#790
OisinKyne merged 1 commit into
mainfrom
fix/agent-resume-strip-metadata

Conversation

@bussyjd

@bussyjd bussyjd commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Problem

obol stack up replays persisted Agent CR manifests via internal/agentcrd.ResumeAll. Those manifests are written by PersistManifest as a full yaml.Marshal of the applied object, which can already include server-managed metadata (resourceVersion, uid, creationTimestamp, managedFields, …).

On cluster recreate / re-apply, ResumeAll previously passed those bytes straight to kubectl.Apply. Kubernetes rejects the update with:

metadata.resourceVersion: Invalid value: 0: must be specified for an update

Root cause: replaying a client-side record that still carries server-managed identity fields.

Fix

  1. internal/stackbackup/cluster.go — export the existing unexported stripObject helper as StripServerManagedMetadata(obj map[string]any) (same body). StripK8sJSON continues to call it for JSON dumps; no behavior change for export/import.

  2. internal/agentcrd/manifest.go — in ResumeAll, after reading each persisted YAML file:

    • yaml.Unmarshal into map[string]any
    • call stackbackup.StripServerManagedMetadata
    • yaml.Marshal back to bytes
    • pass the stripped bytes only to kubectl.Apply

Parse/marshal failures warn and continue (best-effort per agent). warnIfWalletWouldRegenerate still receives the original unstripped bytes (it only reads spec.wallet.create).

Diagram

flowchart LR
  A["Persisted Agent YAML<br/>(resourceVersion, uid,<br/>managedFields, …)"] --> B["yaml.Unmarshal"]
  B --> C["StripServerManagedMetadata<br/>(shared stackbackup helper)"]
  C --> D["yaml.Marshal"]
  D --> E["kubectl apply"]
  E --> F["Apply succeeds<br/>(no resourceVersion:0 error)"]
Loading

Validation

gofmt -l internal/stackbackup/cluster.go internal/agentcrd/manifest.go internal/agentcrd/manifest_test.go internal/stackbackup/stackbackup_test.go
# (no output — all files formatted)

go build ./...
# exit 0

go test ./internal/agentcrd/... ./internal/stackbackup/... -count=1 -v
=== RUN   TestValidateName
...
=== RUN   TestManifestStoreRoundTrip
--- PASS: TestManifestStoreRoundTrip (0.00s)
=== RUN   TestStripServerManagedMetadataOnAgentManifest
--- PASS: TestStripServerManagedMetadataOnAgentManifest (0.00s)
PASS
ok  	github.com/ObolNetwork/obol-stack/internal/agentcrd	1.474s
=== RUN   TestSelectDataNamespaces
...
=== RUN   TestStripK8sJSON
--- PASS: TestStripK8sJSON (0.00s)
=== RUN   TestStripK8sJSONEmptyList
--- PASS: TestStripK8sJSONEmptyList (0.00s)
...
PASS
ok  	github.com/ObolNetwork/obol-stack/internal/stackbackup	2.046s

https://claude.ai/code/session_01PnhCQLz7CHuDBUhWd5xF8v

@OisinKyne
OisinKyne force-pushed the fix/agent-resume-strip-metadata branch from f5c880b to dc70aa2 Compare July 20, 2026 17:41
@OisinKyne
OisinKyne enabled auto-merge (rebase) July 20, 2026 17:41
@OisinKyne
OisinKyne merged commit 660862d into main Jul 20, 2026
9 checks passed
@OisinKyne
OisinKyne deleted the fix/agent-resume-strip-metadata branch July 20, 2026 17:46
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