{"record":{"id":"325fadf46d4ca8e3","repo":"juicedata/juicefs","slug":"put-suffixed-object-failed-s","errorCode":null,"errorMessage":"put `/` suffixed object failed: %s","messagePattern":"put `/` suffixed object failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/objbench.go","lineNumber":1018,"sourceCode":"\t\t}\n\t\tif err := blob.Put(ctx, key, bytes.NewReader(content)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer blob.Delete(ctx, key) //nolint:errcheck\n\t\treturn nil\n\t})\n\n\trunCase(\"put an empty object\", func(blob object.ObjectStorage) error {\n\t\t// Copy empty objects\n\t\tdefer blob.Delete(ctx, \"empty_test_file\") //nolint:errcheck\n\t\tif err := blob.Put(ctx, \"empty_test_file\", bytes.NewReader([]byte{})); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Copy `/` suffixed object\n\t\tdefer blob.Delete(ctx, \"slash_test_file/\") //nolint:errcheck\n\t\tif err := blob.Put(ctx, \"slash_test_file/\", bytes.NewReader([]byte(\"1\"))); err != nil {\n\t\t\treturn fmt.Errorf(\"put `/` suffixed object failed: %s\", err)\n\t\t}\n\t\treturn nil\n\t})\n\n\trunCase(\"multipart upload\", func(blob object.ObjectStorage) (err error) {\n\t\tdefer func() {\n\t\t\terr = warning(err)\n\t\t}()\n\n\t\tkey := \"multi_test_file\"\n\t\tif err = blob.CompleteUpload(ctx, key, \"notExistsUploadId\", []*object.Part{}); err != utils.ErrNotSUP {\n\t\t\tdefer blob.Delete(ctx, key) //nolint:errcheck\n\t\t\tupload, err := blob.CreateMultipartUpload(ctx, key)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"create multipart upload failed: %s\", err)\n\t\t\t}\n\t\t\ttotal := 3\n\t\t\tseed := make([]byte, upload.MinPartSize)","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/objbench.go#L1000-L1036","documentation":"objbench tests that the backend can store an object whose key ends with '/' ('slash_test_file/'), wrapping Put failures with this message. Some stores treat trailing-slash keys specially (as 'directories') and reject them.","triggerScenarios":"`blob.Put(ctx, \"slash_test_file/\", ...)` returns an error during the slash-key test case.","commonSituations":"Backends that forbid zero-byte or trailing-slash keys; drivers that normalize/strip the trailing slash before sending; S3-compatible stores with path-mode restrictions.","solutions":["Read the wrapped backend error for the root cause","Check the driver doesn't strip or transform the trailing slash in keys","Verify the backend permits keys ending in '/'","If unsupported, accept it as a backend limitation"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// probe trailing-slash key support\nif err := blob.Put(ctx, \"probe/\", bytes.NewReader(nil)); err != nil { /* backend rejects '/'-suffixed keys */ }\n_ = blob.Delete(ctx, \"probe/\")","typeGuard":null,"tryCatchPattern":"if err := blob.Put(ctx, \"slash_test_file/\", r); err != nil {\n    // fall back or report backend limitation\n    return fmt.Errorf(\"put `/` suffixed object failed: %s\", err)\n}","preventionTips":["Confirm the backend allows keys ending in '/'","Ensure the driver does not strip or normalize trailing slashes","Accept as a known limitation on restrictive backends"],"tags":["object-storage","put","key-encoding"],"backgroundTag":"api-request-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}