Skip to content

fix: strip OCI chart pull progress from rendered manifests (#1040) - #1041

Merged
yxxhero merged 1 commit into
masterfrom
fix/oci-three-way-merge-1040
Aug 1, 2026
Merged

fix: strip OCI chart pull progress from rendered manifests (#1040)#1041
yxxhero merged 1 commit into
masterfrom
fix/oci-three-way-merge-1040

Conversation

@yxxhero

@yxxhero yxxhero commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Problem

helm diff upgrade --three-way-merge (and --take-ownership) fails with OCI-hosted charts because Helm writes the chart pull progress to stdout before the rendered manifests:

Pulled: public.ecr.aws/karpenter/karpenter:1.9.0
Digest: sha256:8e3952caafd208cb888fbf97467cd04a4a024a3fba64c84af73039040cc6a371
---
# Source: ...

The helm template code path in helm-diff used a no-op filter, so these lines leaked into the manifest buffer and got parsed as a YAML document lacking a Kind, breaking kubeclient.Build():

Error: unable to generate manifests: unable to build kubernetes objects from new release manifest:
unable to decode "": Object 'Kind' is missing in '{"Digest":"...","Pulled":"..."}'

This only affects the helm template path. The HELM_DIFF_USE_UPGRADE_DRY_RUN=true path works because extractManifestFromHelmUpgradeDryRunOutput only keeps the MANIFEST:/HOOKS: sections, discarding the leading progress output.

Fixes #1040.

Fix

Strip Helm's OCI chart pull progress lines (Pulled:, Digest:, Pulling:) from the helm template output before it is returned, fixing the leak at the source. This benefits both manifest.Generate() (three-way-merge) and the --take-ownership Build() call, which both kubeclient.Build() the templated manifest.

Why is the regex safe?

The lines are matched at the start of a line (column 0). Top-level Kubernetes manifest keys are apiVersion/kind/metadata/spec and are never Pulled/Digest/Pulling. Any homonymous keys nested inside a manifest (e.g. under data: or metadata:) are indented and therefore not matched.

Verification

  • go build ./...
  • go vet ./...
  • golangci-lint run ./cmd/ → 0 issues
  • go test ./... → all pass
  • Added TestStripOCIPullProgress covering: progress prepended to manifests, all three line variants, no-op on clean output, indented keys preserved, progress-only input, and empty input.

Checklist

  • The fix targets the root cause (the leaking helm template filter), so it covers three-way-merge and take-ownership paths.
  • No change to existing behavior for non-OCI charts.

@yxxhero
yxxhero force-pushed the fix/oci-three-way-merge-1040 branch 2 times, most recently from 450c302 to 7acd90a Compare August 1, 2026 07:26
When templating an OCI-hosted chart (or a chart with OCI subcharts),
Helm writes the chart pull progress to stdout before the rendered
manifests:

  Pulled: public.ecr.aws/karpenter/karpenter:1.9.0
  Digest: sha256:8e3952caafd208cb888fbf97467cd04a4a024a3fba64c84af73039040cc6a371
  ---
  # Source: ...

These progress lines leaked into the manifest buffer returned by the
`helm template` code paths and got parsed as a YAML document lacking a
Kind, breaking the downstream three-way-merge and take-ownership
`kubeclient.Build()` calls:

  unable to decode "": Object 'Kind' is missing in
  '{"Digest":"...","Pulled":"..."}'

This affected `helm diff upgrade --three-way-merge`/`--take-ownership`
(the regular diff and `helm diff local` paths were not broken because
`manifest.Parse()` already skips documents without apiVersion/kind).

Strip the OCI pull progress lines ("Pulled:", "Digest:", and
defensively "Pulling:") from the `helm template` output in both places
that capture it:
  * cmd/helm.go `template()`  -> upgrade (three-way-merge / take-ownership)
  * cmd/local.go `renderChart()` -> local diff

Stripping at the source ensures `manifest.Generate()` (three-way-merge),
the take-ownership `Build()` call, and `manifest.Parse()` all receive
clean manifests, and keeps both `helm template` callers symmetric.

The lines are matched at the start of a line (column 0), which is safe
because top-level Kubernetes manifest keys are apiVersion/kind/metadata/
spec and never "Pulled"/"Digest"/"Pulling"; any homonymous keys nested
inside a manifest are indented and therefore not matched.

Fixes #1040

Signed-off-by: yxxhero <aiopsclub@163.com>
@yxxhero
yxxhero force-pushed the fix/oci-three-way-merge-1040 branch from 7acd90a to 93dce5f Compare August 1, 2026 07:47
@yxxhero
yxxhero merged commit 6153341 into master Aug 1, 2026
25 checks passed
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] --three-way-merge fails when using OCI charts due to OCI pull output leaking into manifest buffer

1 participant