Describe the bug
When the Helm build-info flow works with OCI charts stored under a non-root path inside an Artifactory OCI repository, it can resolve the wrong Artifactory path and miss artifacts that do exist.
This showed up in two concrete places:
jf helm push post-push build-info collection
- OCI dependency layer resolution in
addOCILayersForDependency
In both cases, the root problem is the same: the follow-up lookup assumes the OCI storage path inside Artifactory is always:
<chart-name>/<chart-version>
That assumption is only valid when the chart was pushed at the repository root. For valid OCI repository URLs that include additional path segments, the real storage path is:
<resolved-subpath>/<chart-name>/<chart-version>
As a result, the CLI searches the wrong path and misses manifests/layers that were actually uploaded and do exist in Artifactory.
Current behavior
Two broken behaviors can be observed today when the OCI URL contains a non-root path:
jf helm push can succeed, but the follow-up build-info collection step can fail because it looks under chart/version instead of the real subpath/chart/version.
- OCI dependency layer resolution can silently miss dependency artifacts for the same reason:
dep.Id only contains chart:version, while the missing subpath lives in dep.Repository.
Examples of valid OCI repository layouts:
- repo in host, no path
oci://helm-repo.artifactory.acme.example.com
- repo in host, with subpath
oci://helm-repo.artifactory.acme.example.com/team-a/charts
- repo in path, no extra subpath
oci://artifactory.acme.example.com/helm-repo
- repo in path, with extra subpath
oci://artifactory.acme.example.com/helm-repo/team-a/charts
Before the fix, the root-only cases work, but the non-root cases can fail because the lookup path ignores the resolved subpath.
This is especially confusing because the OCI artifacts are already present in Artifactory. The failure happens later, during build-info/layer resolution.
Reproduction steps
One concrete push reproduction path is:
- Push a Helm chart to a valid OCI URL with a non-root path, for example:
oci://helm-repo.artifactory.acme.example.com/team-a/charts
- or
oci://artifactory.acme.example.com/helm-repo/team-a/charts
- Run the push through the JFrog CLI build-info flow (
jf helm push ...).
- Observe that the native Helm push succeeds.
- Observe that the follow-up build-info collection looks for OCI artifacts under
chart-name/chart-version instead of under team-a/charts/chart-name/chart-version.
- Build-info collection fails to find the uploaded manifest/layers even though the artifact exists in Artifactory.
One concrete OCI dependency reproduction path is:
- Define a dependency with an OCI repository URL that contains a non-root path, for example:
oci://helm-repo.artifactory.acme.example.com/team-a/charts
- or
oci://artifactory.acme.example.com/helm-repo/team-a/charts
- Ensure the dependency is stored in Artifactory under the real path:
team-a/charts/chart-name/chart-version
- Run the build-info flow that resolves OCI dependency layers.
- Observe that the dependency lookup searches
chart-name/chart-version instead of team-a/charts/chart-name/chart-version.
- The dependency is skipped or left unresolved even though its OCI artifacts exist.
Expected behavior
The Helm OCI build-info flow should resolve artifacts correctly both at the repository root and under non-root subpaths.
Expected behavior:
- host-only root pushes still work as before
- path-based root pushes still work as before
- host-based pushes with subpath resolve the correct repo key and subpath
- path-based pushes with subpath resolve the correct repo key and subpath
- OCI dependency resolution uses the same real Artifactory storage semantics for subpath cases
- once repo key and subpath are resolved, the CLI searches Artifactory using the real storage path:
subpath/chart-name/chart-version
- build properties / manifest-folder annotation use the same resolved Artifactory location instead of assuming a root-only chart layout
- OCI dependency layer resolution uses the same resolved storage path instead of assuming the dependency chart is at repo root
JFrog CLI-Core version
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260414083544-243b4d55328b
JFrog CLI-Artifactory version
source checkout (commit e9db596)
JFrog CLI version (if applicable)
jf version 2.100.0
Operating system type and version
macOS darwin arm64
JFrog Artifactory version
N.A
Additional context
- This report is limited to OCI behavior.
- It covers both
jf helm push post-push build-info for non-root subpaths and jf helm dependency OCI dependency layer resolution for non-root subpaths.
- Classic Helm remains out of scope and unchanged.
Describe the bug
When the Helm build-info flow works with OCI charts stored under a non-root path inside an Artifactory OCI repository, it can resolve the wrong Artifactory path and miss artifacts that do exist.
This showed up in two concrete places:
jf helm pushpost-push build-info collectionaddOCILayersForDependencyIn both cases, the root problem is the same: the follow-up lookup assumes the OCI storage path inside Artifactory is always:
<chart-name>/<chart-version>That assumption is only valid when the chart was pushed at the repository root. For valid OCI repository URLs that include additional path segments, the real storage path is:
<resolved-subpath>/<chart-name>/<chart-version>As a result, the CLI searches the wrong path and misses manifests/layers that were actually uploaded and do exist in Artifactory.
Current behavior
Two broken behaviors can be observed today when the OCI URL contains a non-root path:
jf helm pushcan succeed, but the follow-up build-info collection step can fail because it looks underchart/versioninstead of the realsubpath/chart/version.dep.Idonly containschart:version, while the missing subpath lives indep.Repository.Examples of valid OCI repository layouts:
oci://helm-repo.artifactory.acme.example.comoci://helm-repo.artifactory.acme.example.com/team-a/chartsoci://artifactory.acme.example.com/helm-repooci://artifactory.acme.example.com/helm-repo/team-a/chartsBefore the fix, the root-only cases work, but the non-root cases can fail because the lookup path ignores the resolved subpath.
This is especially confusing because the OCI artifacts are already present in Artifactory. The failure happens later, during build-info/layer resolution.
Reproduction steps
One concrete push reproduction path is:
oci://helm-repo.artifactory.acme.example.com/team-a/chartsoci://artifactory.acme.example.com/helm-repo/team-a/chartsjf helm push ...).chart-name/chart-versioninstead of underteam-a/charts/chart-name/chart-version.One concrete OCI dependency reproduction path is:
oci://helm-repo.artifactory.acme.example.com/team-a/chartsoci://artifactory.acme.example.com/helm-repo/team-a/chartsteam-a/charts/chart-name/chart-versionchart-name/chart-versioninstead ofteam-a/charts/chart-name/chart-version.Expected behavior
The Helm OCI build-info flow should resolve artifacts correctly both at the repository root and under non-root subpaths.
Expected behavior:
subpath/chart-name/chart-versionJFrog CLI-Core version
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260414083544-243b4d55328b
JFrog CLI-Artifactory version
source checkout (commit e9db596)
JFrog CLI version (if applicable)
jf version 2.100.0
Operating system type and version
macOS darwin arm64
JFrog Artifactory version
N.A
Additional context
jf helm pushpost-push build-info for non-root subpaths andjf helm dependencyOCI dependency layer resolution for non-root subpaths.