argoproj/argo-workflows · error
get Rel path from %s to %s error: %w
Error message
get Rel path from %s to %s error: %w
What it means
When downloading an OSS 'directory' artifact, GetOssDirectory (workflow/artifacts/oss/oss.go:556) computes each listed object key's path relative to the directory prefix via filepath.Rel so it can recreate the tree under the local destination. If filepath.Rel fails — it cannot produce a relative path, e.g. when the object key cannot be reached from the base prefix — the error is wrapped as 'get Rel path from %s to %s error: %w'.
Source
Thrown at workflow/artifacts/oss/oss.go:558
if err != nil {
return false, err
}
if len(rst.CommonPrefixes)+len(rst.Objects) > 0 {
return true, nil
}
return false, nil
}
// GetOssDirectory download an OSS "directory" to local path
func GetOssDirectory(ctx context.Context, bucket *oss.Bucket, objectName, path string) error {
files, err := ListOssDirectory(ctx, bucket, objectName)
if err != nil {
return err
}
for _, f := range files {
innerName, err := filepath.Rel(objectName, f)
if err != nil {
return fmt.Errorf("get Rel path from %s to %s error: %w", f, objectName, err)
}
fpath := filepath.Join(path, innerName)
if strings.HasSuffix(f, "/") {
err = os.MkdirAll(fpath, 0o700)
if err != nil {
return fmt.Errorf("mkdir %s error: %w", fpath, err)
}
continue
}
dirPath := filepath.Dir(fpath)
err = os.MkdirAll(dirPath, 0o700)
if err != nil {
return fmt.Errorf("mkdir %s error: %w", dirPath, err)
}
err = bucket.GetObjectToFile(f, fpath)
if err != nil {
logging.RequireLoggerFromContext(ctx).WithFields(logging.Fields{"key": f, "path": fpath}).WithError(err).Warn(ctx, "failed to load object")View on GitHub (pinned to 35bff19146)
Solutions
- Ensure the objectName passed to GetOssDirectory is exactly the prefix used for listing, with a trailing '/' for directory keys (ListOssDirectory normalizes it, so pass the same original key).
- Verify listed keys all begin with the objectName prefix; if they do not, fix the caller/listing logic rather than the path math.
- If keys may escape the base (contain '..'), sanitize or reject them before calling GetOssDirectory.
- On Windows, check the keys use consistent separators ('/' vs '\\') acceptable to filepath.Rel.
Example fix
// before err := GetOssDirectory(ctx, bucket, "my-dir", "/tmp/art") // listing keys: "other/x.txt" // after err := GetOssDirectory(ctx, bucket, "my-dir/", "/tmp/art") // keys "my-dir/x.txt" rel correctly
Defensive patterns
Strategy: validation
Validate before calling
if !strings.HasPrefix(f, strings.TrimSuffix(objectName, "/")+"/") {
return fmt.Errorf("key %q is not under prefix %q; refusing Rel", f, objectName)
} Prevention
- Pass the same object key to GetOssDirectory that was used for listing, unmodified.
- Use trailing-slash directory keys consistently ('my-dir/').
- Sanitize listed keys for '..' segments before path computation to avoid traversal and Rel errors.
- On Windows, verify OSS keys don't mix separators.
When it happens
Trigger: Calling GetOssDirectory with an objectName (base) that does not prefix the listed file keys. Practically this happens when the bucket listing returns keys outside the requested prefix — for example the base objectName lacks the trailing '/' that ListOssDirectory normalizes on, or the caller passes a different/mutated key than the one used to list, so keys like 'a/b/c.txt' are Rel'd against base 'a' or an unrelated path.
Common situations: Manually invoking the artifact driver with a key missing its trailing slash; a custom driver/plugin passing an absolute vs relative mismatch; OSS keys containing '..' or symlink-like segments that make filepath.Rel return an error on Windows; writing tests that call GetOssDirectory with an objectName that doesn't match the stubbed listing.
Related errors
- failed to create new OSS client: %w
- mkdir %s error: %w
- failed to get file: %w
- failed to test if %s/%s is a directory: %w
- failed get directory: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/dde95781cc3a00c7.
Report an issue: GitHub.