Skip to content

fix(profiles): allow patches to add into empty maps and lists - #10195

Open
bhargavikvmpl-2001 wants to merge 2 commits into
GoogleContainerTools:mainfrom
bhargavikvmpl-2001:fix/profile-patch-add-into-empty-collections
Open

bhargavikvmpl-2001 wants to merge 2 commits into
GoogleContainerTools:mainfrom
bhargavikvmpl-2001:fix/profile-patch-add-into-empty-collections

Conversation

@bhargavikvmpl-2001

@bhargavikvmpl-2001 bhargavikvmpl-2001 commented Sep 29, 2026 •

Copy link
Copy Markdown

Fixes: #5766
Fixes: #8637

Description

applyProfile re-marshals the parsed SkaffoldConfig to YAML before applying profile patches. Fields such as docker.buildArgs and helm.releases are omitempty, so an empty collection the user declared (buildArgs: {}, releases: []) is dropped from that document. An add into it then fails with invalid path, because the parent no longer exists. The yaml-patch library itself handles add correctly; the parent is just missing by the time it runs.

This PR adds marshalForPatching, which encodes the config to a yaml.Node and then walks the struct alongside the node tree to restore maps and slices that are empty but non-nil. A YAML {}/[] decodes to a non-nil empty value, while an unset field stays nil, so only collections the user actually wrote come back. Types with a custom MarshalYAML are left alone.

A note on the approach: in my comment on #5766 I suggested patching the original YAML node. That doesn't work, because profile fields are overlaid onto the struct before patches run, and older configs are upgraded first. Keeping user-declared empty collections gets the same result without those problems.

User facing changes

Before: with buildArgs: {} (or releases: []), op: add to /build/artifacts/0/docker/buildArgs/profile (or /deploy/helm/releases/-) fails with invalid path.

After: the patch applies, including when several profiles each add into the same empty collection.

A bare buildArgs: (YAML null) still has no parent to add into, consistent with RFC 6902; buildArgs: {} is the way to declare an empty map.

Testing

  • TestApplyPatchIntoEmptyCollections covers both issues, including two profiles adding into the same empty buildArgs. It fails on main with the error from Patches operation 'add' cannot add new keys as show in the JsonPatch example #5766 and passes with this change.
  • TestMarshalForPatching checks that nil collections are still omitted, an empty map is kept, and an empty slice inside an otherwise empty struct is kept.
  • For all 86 example configs under integration/examples and integration/testdata that parse at the latest schema, marshalForPatching output is byte-identical to yaml.Marshal.
  • go test ./pkg/skaffold/schema/... ./pkg/skaffold/parser/..., go vet and gofmt pass.

@bhargavikvmpl-2001
bhargavikvmpl-2001 requested a review from a team as a code owner September 29, 2026 15:29
@google-cla

google-cla Bot commented Sep 29, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

applyProfile re-marshals the parsed config before applying JSON patches.
Because fields such as docker.buildArgs and helm.releases are omitempty,
an empty collection the user declared (`buildArgs: {}`, `releases: []`)
was dropped from the document, so an `add` into it failed with
"invalid path".

Marshal the config for patching so that empty but non-nil maps and
slices are kept. nil collections are still omitted, so output for
configs without explicit empty collections is unchanged.

Fixes GoogleContainerTools#5766
Fixes GoogleContainerTools#8637
@bhargavikvmpl-2001
bhargavikvmpl-2001 force-pushed the fix/profile-patch-add-into-empty-collections branch from 2dd4df3 to e8ae4c0 Compare September 29, 2026 22:03
@bhargavikvmpl-2001

Copy link
Copy Markdown
Author

Hi maintainers, could someone approve the workflow runs for this PR? As a first-time contributor, the unit, integration and lint workflows are waiting for approval. Locally, the unit tests (./pkg/... ./cmd/... ./hack/...) and make linters pass. Thanks!

Allow 2026 in the boilerplate year check so new files with a 2026
copyright header pass hack/boilerplate.sh, and use reflect.Pointer
instead of the deprecated reflect.Ptr alias flagged by govet.
@bhargavikvmpl-2001
bhargavikvmpl-2001 force-pushed the fix/profile-patch-add-into-empty-collections branch from a891460 to a288034 Compare October 4, 2026 23:16

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Patches applied to end of empty list error out Patches operation 'add' cannot add new keys as show in the JsonPatch example

1 participant