juicedata/juicefs · error
list should return 1 keys, but got %d
Error message
list should return 1 keys, but got %d
What it means
In the non-filesystem branch of objbench's "list objects" case, `listAll(ctx, blob, "", "", 1)` must return exactly 1 key (the single "test" object put just before). This message means the backend returned a different number of keys for a maxKeys=1 list, violating list pagination/limit semantics.
Source
Thrown at cmd/objbench.go:925
now := time.Now()
if objs[1].Mtime().Before(now.Add(-30*time.Second)) || objs[1].Mtime().After(now.Add(time.Second*30)) {
return fmt.Errorf("mtime of key should be within 30 seconds, but got %s", objs[1].Mtime().Sub(now))
}
} else {
return fmt.Errorf("list failed: %s", err)
}
objs, err = listAll(ctx, blob, "", "test2", 1)
if err != nil {
return fmt.Errorf("list failed: %s", err)
} else if len(objs) != 0 {
return fmt.Errorf("list should not return anything, but got %d", len(objs))
}
} else {
objs, err2 := listAll(ctx, blob, "", "", 1)
if err2 == nil {
if len(objs) != 1 {
return fmt.Errorf("list should return 1 keys, but got %d", len(objs))
}
if objs[0].Key() != key {
return fmt.Errorf("first key should be test, but got %s", objs[0].Key())
}
if objs[0].Size() != 5 {
return fmt.Errorf("size of first key shold be 5, but got %v", objs[0].Size())
}
now := time.Now()
if objs[0].Mtime().Before(now.Add(-30*time.Second)) || objs[0].Mtime().After(now.Add(time.Second*30)) {
return fmt.Errorf("mtime of key should be within 30 seconds, but got %s", objs[0].Mtime().Sub(now))
}
} else {
return fmt.Errorf("list failed: %s", err2)
}
objs, err2 = listAll(ctx, blob, "", "test2", 1)
if err2 != nil {
return fmt.Errorf("list failed: %s", err2)View on GitHub (pinned to c9a67b23e8)
Solutions
- Run objbench against a clean, dedicated bucket so exactly one key matches.
- Fix the backend's List to respect the requested maxKeys (1 here) in a single page.
- Verify the earlier Put of key "test" succeeded before List is called.
- Check for stale objects with the bench key from previous runs and delete them.
Example fix
// backend List: honor limit
if len(result) > maxKeys { result = result[:maxKeys] } Defensive patterns
Strategy: validation
Validate before calling
objs, _ := listAll(ctx, blob, "", "", 10)
if len(objs) != 1 {
return fmt.Errorf("bucket not clean; got %d keys, expected 1", len(objs))
} Prevention
- Benchmark only against a clean, dedicated bucket.
- Custom backends must honor the maxKeys parameter.
- Verify Put success before asserting on list counts.
When it happens
Trigger: `juicefs objbench` on a non-filesystem object storage that ignores the maxKeys limit and returns more objects, or returns zero keys despite the put succeeding, or lists leftover keys in a dirty bucket.
Common situations: Custom backend that ignores the `maxKeys`/limit parameter; shared bucket polluted with other keys; put failed silently or eventual consistency hiding the new key.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- list failed: %s
- list should not return anything, but got %d
- list should return 2 keys, but got %d
- first key should be empty string, but got %s
- first object size should be 0, but got %d
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/9ee126a908853a73.
Report an issue: GitHub.