{"record":{"id":"8e26907ffba4eaa4","repo":"juicedata/juicefs","slug":"invalid-key-s","errorCode":null,"errorMessage":"invalid key %s","messagePattern":"invalid key (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/redis.go","lineNumber":4116,"sourceCode":"\t\tclose(delKeys)\n\t}()\n\n\tvar ss []Slice\n\tvar rs []*redis.IntCmd\n\tfor key := range delKeys {\n\t\tvar clean bool\n\t\ttask := func(tx *redis.Tx) error {\n\t\t\tss = ss[:0]\n\t\t\trs = rs[:0]\n\t\t\tval, err := tx.HGet(ctx, m.delSlices(), key).Result()\n\t\t\tif err == redis.Nil {\n\t\t\t\treturn nil\n\t\t\t} else if err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tps := strings.Split(key, \"_\")\n\t\t\tif len(ps) != 2 {\n\t\t\t\treturn fmt.Errorf(\"invalid key %s\", key)\n\t\t\t}\n\t\t\tts, err := strconv.ParseInt(ps[1], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"invalid key %s, fail to parse timestamp\", key)\n\t\t\t}\n\n\t\t\tm.decodeDelayedSlices([]byte(val), &ss)\n\t\t\tclean, err = scan(ss, ts)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif clean {\n\t\t\t\t_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {\n\t\t\t\t\tfor _, s := range ss {\n\t\t\t\t\t\trs = append(rs, pipe.HIncrBy(ctx, m.sliceRefs(), m.sliceKey(s.Id, s.Size), -1))\n\t\t\t\t\t}\n\t\t\t\t\tpipe.HDel(ctx, m.delSlices(), key)\n\t\t\t\t\tid, err := strconv.ParseUint(ps[0], 10, 64)","sourceCodeStart":4098,"sourceCodeEnd":4134,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/redis.go#L4098-L4134","documentation":"While cleaning up delayed slice deletions, entries in the delSlices hash are keyed by \"<sliceId>_<timestamp>\". A key that does not split into exactly two underscore-separated parts cannot be parsed, so cleanup aborts with this error rather than acting on an unknown key format.","triggerScenarios":"A foreign or manually inserted entry inside the delSlices hash, or a value written under a different key convention (e.g. by a different code path or old/new client mismatch) encountered during delayed-slice cleanup scan.","commonSituations":"Manual Redis surgery on metadata keys; entries left by a very old JuiceFS version with a different key scheme; accidental key collisions from sharing a Redis DB with other applications.","solutions":["Inspect the offending key with redis-cli HKEYS on the delSlices hash and identify where it came from.","If it is foreign data (another app sharing the Redis DB), move the app to its own DB index or key prefix.","If it is stale/unknown and its slices are accounted for, remove the hash entry deliberately and re-run cleanup.","Ensure all clients run a JuiceFS version using the same delSlices key format."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for _, k := range hashKeys {\n    if len(strings.Split(k, \"_\")) != 2 { fmt.Printf(\"malformed delSlices key %q — inspect before cleanup\\n\", k) }\n}","typeGuard":null,"tryCatchPattern":"if err := cleanup(ctx); err != nil && strings.Contains(err.Error(), \"invalid key\") {\n    logger.Errorf(\"foreign/corrupt metadata key detected: %v\", err)\n    // halt automated cleanup, reconcile manually\n}","preventionTips":["Give JuiceFS an exclusive Redis DB index — no other apps writing keys","Never insert or rename metadata keys by hand","Scan hashes for foreign keys after any restore operation"],"tags":["redis","key-format","cleanup","delayed-slices"],"backgroundTag":"invalid-argument-format","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}