{"record":{"id":"dde95781cc3a00c7","repo":"argoproj/argo-workflows","slug":"get-rel-path-from-s-to-s-error-w","errorCode":null,"errorMessage":"get Rel path from %s to %s error: %w","messagePattern":"get Rel path from (.+?) to (.+?) error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/oss/oss.go","lineNumber":558,"sourceCode":"\tif err != nil {\n\t\treturn false, err\n\t}\n\tif len(rst.CommonPrefixes)+len(rst.Objects) > 0 {\n\t\treturn true, nil\n\t}\n\treturn false, nil\n}\n\n// GetOssDirectory download an OSS \"directory\" to local path\nfunc GetOssDirectory(ctx context.Context, bucket *oss.Bucket, objectName, path string) error {\n\tfiles, err := ListOssDirectory(ctx, bucket, objectName)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, f := range files {\n\t\tinnerName, err := filepath.Rel(objectName, f)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"get Rel path from %s to %s error: %w\", f, objectName, err)\n\t\t}\n\t\tfpath := filepath.Join(path, innerName)\n\t\tif strings.HasSuffix(f, \"/\") {\n\t\t\terr = os.MkdirAll(fpath, 0o700)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"mkdir %s error: %w\", fpath, err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tdirPath := filepath.Dir(fpath)\n\t\terr = os.MkdirAll(dirPath, 0o700)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"mkdir %s error: %w\", dirPath, err)\n\t\t}\n\n\t\terr = bucket.GetObjectToFile(f, fpath)\n\t\tif err != nil {\n\t\t\tlogging.RequireLoggerFromContext(ctx).WithFields(logging.Fields{\"key\": f, \"path\": fpath}).WithError(err).Warn(ctx, \"failed to load object\")","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/oss/oss.go#L540-L576","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nerr := GetOssDirectory(ctx, bucket, \"my-dir\", \"/tmp/art\") // listing keys: \"other/x.txt\"\n// after\nerr := GetOssDirectory(ctx, bucket, \"my-dir/\", \"/tmp/art\") // keys \"my-dir/x.txt\" rel correctly","handlingStrategy":"validation","validationCode":"if !strings.HasPrefix(f, strings.TrimSuffix(objectName, \"/\")+\"/\") {\n    return fmt.Errorf(\"key %q is not under prefix %q; refusing Rel\", f, objectName)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["oss","path-resolution","artifact-download"],"backgroundTag":"relative-path-resolution-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}