{"record":{"id":"d7f25ef6f4b3f792","repo":"juicedata/juicefs","slug":"first-object-size-should-be-0-but-got-d","errorCode":null,"errorMessage":"first object size should be 0, but got %d","messagePattern":"first object size should be 0, but got (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/objbench.go","lineNumber":899,"sourceCode":"\t})\n\n\trunCase(\"list objects\", func(blob object.ObjectStorage) error {\n\t\tbr := []byte(\"hello\")\n\t\tif err := blob.Put(ctx, key, bytes.NewReader(br)); err != nil {\n\t\t\treturn fmt.Errorf(\"put object failed: %s\", err)\n\t\t}\n\t\tdefer blob.Delete(ctx, key) //nolint:errcheck\n\t\tif isFileSystem {\n\t\t\tobjs, err := listAll(ctx, blob, \"\", \"\", 2)\n\t\t\tif err == nil {\n\t\t\t\tif len(objs) != 2 {\n\t\t\t\t\treturn fmt.Errorf(\"list should return 2 keys, but got %d\", len(objs))\n\t\t\t\t}\n\t\t\t\tif objs[0].Key() != \"\" {\n\t\t\t\t\treturn fmt.Errorf(\"first key should be empty string, but got %s\", objs[0].Key())\n\t\t\t\t}\n\t\t\t\tif objs[0].Size() != 0 {\n\t\t\t\t\treturn fmt.Errorf(\"first object size should be 0, but got %d\", objs[0].Size())\n\t\t\t\t}\n\t\t\t\tif objs[1].Key() != key {\n\t\t\t\t\treturn fmt.Errorf(\"first key should be test, but got %s\", objs[1].Key())\n\t\t\t\t}\n\t\t\t\tif objs[1].Size() != 5 {\n\t\t\t\t\treturn fmt.Errorf(\"size of first key shold be 5, but got %v\", objs[1].Size())\n\t\t\t\t}\n\t\t\t\tnow := time.Now()\n\t\t\t\tif objs[1].Mtime().Before(now.Add(-30*time.Second)) || objs[1].Mtime().After(now.Add(time.Second*30)) {\n\t\t\t\t\treturn fmt.Errorf(\"mtime of key should be within 30 seconds, but got %s\", objs[1].Mtime().Sub(now))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"list failed: %s\", err)\n\t\t\t}\n\n\t\t\tobjs, err = listAll(ctx, blob, \"\", \"test2\", 1)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"list failed: %s\", err)","sourceCodeStart":881,"sourceCodeEnd":917,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/objbench.go#L881-L917","documentation":"Raised in the objbench 'list objects' filesystem case: the first listed entry (the directory placeholder for \"\") must have Size() == 0, but a nonzero size was returned. This asserts that filesystem backends report directory entries with zero size, matching how object listings emulate directories.","triggerScenarios":"After listAll returns 2 entries with the correct keys, objs[0].Size() != 0 — the backend filled in a real byte size (e.g. directory stat size like 4096, or an object's size) for the directory entry.","commonSituations":"A custom file backend that calls os.Stat on the directory and reports its allocated size; a backend that reuses a struct with a stale size field; listing a prefix that matches a real object with the same path.","solutions":["In the backend's List, hardcode Size()=0 for synthesized directory entries instead of the directory's stat size.","Ensure the size field is reset/zeroed for placeholder entries.","Test against the reference file:// backend behavior in pkg/object.","Clean the test directory of stray keys that could be mistaken for the dir entry.","Rerun objbench."],"exampleFix":"// before\nreturn &entry{key: \"\", size: fi.Size()}, nil // 4096 for dirs\n// after\nreturn &entry{key: \"\", size: 0}, nil // dir entry must be size 0","handlingStrategy":"type-guard","validationCode":"objs, _ := listAll(ctx, blob, \"\", \"\", 2)\nif len(objs) > 0 && objs[0].Key() == \"\" && objs[0].Size() != 0 {\n    log.Printf(\"dir entry has nonzero size: %d\", objs[0].Size())\n}","typeGuard":"func isZeroSizeDirEntry(o object.Object) bool {\n    return o.Key() == \"\" && o.Size() == 0\n}","tryCatchPattern":"if o := objs[0]; o.Key() == \"\" && o.Size() != 0 {\n    log.Printf(\"backend reports dir size %d; treat as 0\", o.Size())\n}","preventionTips":["Hardcode size 0 for synthesized directory entries.","Do not stat directories for list entry sizes.","Unit-test List output shapes for file backends.","Run objbench before deploying custom stores."],"tags":["object-storage","list","size","filesystem"],"backgroundTag":"unexpected-api-response-shape","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"}