{"record":{"id":"375b61dc10238454","repo":"juicedata/juicefs","slug":"invalid-value-for-delslices-s-v","errorCode":null,"errorMessage":"invalid value for delSlices %s: %v","messagePattern":"invalid value for delSlices (.+?): (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/redis.go","lineNumber":3740,"sourceCode":"\t\t\t\tlogger.Warnf(\"Invalid key %s\", key)\n\t\t\t\tcontinue\n\t\t\t} else if ts >= uint64(edge) {\n\t\t\t\tcontinue\n\t\t\t} else if id, e := strconv.ParseUint(ps[0], 10, 64); e != nil {\n\t\t\t\tlogger.Warnf(\"Invalid key %s\", key)\n\t\t\t\tcontinue\n\t\t\t} else if err := r.txn(ctx, func(tx *redis.Tx) error {\n\t\t\t\tss, rs = ss[:0], rs[:0]\n\t\t\t\tval, e := tx.HGet(ctx, r.delSlices(), key).Result()\n\t\t\t\tif e == redis.Nil {\n\t\t\t\t\treturn nil\n\t\t\t\t} else if e != nil {\n\t\t\t\t\treturn e\n\t\t\t\t}\n\t\t\t\tbuf := []byte(val)\n\t\t\t\tr.decodeDelayedSlices(buf, &ss)\n\t\t\t\tif len(ss) == 0 {\n\t\t\t\t\treturn fmt.Errorf(\"invalid value for delSlices %s: %v\", key, buf)\n\t\t\t\t}\n\t\t\t\t_, e = 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, r.sliceRefs(), r.sliceKey(s.Id, s.Size), -1))\n\t\t\t\t\t}\n\t\t\t\t\tpipe.HDel(ctx, r.delSlices(), key)\n\t\t\t\t\tr.genLog(ctx, pipe, time.Now(), \"CLEANUP_DELAYED_SLICES(%d,%d)\", id, int64(ts))\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t\treturn e\n\t\t\t}, r.delSlices()); err != nil {\n\t\t\t\tlogger.Warnf(\"Cleanup delSlices %s: %s\", key, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor i, s := range ss {\n\t\t\t\tif rs[i].Err() == nil && rs[i].Val() < 0 {\n\t\t\t\t\tr.deleteSlice(s.Id, s.Size)\n\t\t\t\t\tcount++","sourceCodeStart":3722,"sourceCodeEnd":3758,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/redis.go#L3722-L3758","documentation":"During delayed slice-reference cleanup, the stored value of the `delSlices` hash entry for `key` failed to decode into any delayed slice records (decodeDelayedSlices produced an empty list). This indicates the persisted value is corrupt, truncated, or was written by an incompatible/older format, so the cleanup transaction refuses to proceed to avoid decrementing the wrong slice refcounts.","triggerScenarios":"A hash entry in the delSlices key whose value is empty or undecodable when the delayed cleanup transaction scans and processes it (e.g. after a manual Redis edit, a restore from a partial backup, or data written by a client version with a different encoding).","commonSituations":"Restoring metadata from an incomplete dump/backup; hand-editing or flushing parts of Redis; mixing very old client versions that wrote a legacy delSlices format.","solutions":["Inspect the value: redis-cli HGET <delSlices-key> <key> and compare against the DelayedSlices encoding used by decodeDelayedSlices.","If the value is corrupt and the corresponding slices are known-deleted, safely remove the hash entry (HDEL) so cleanup stops failing, after confirming slice refcounts are correct.","Upgrade all clients to a version sharing the same delayed-slices encoding, then retry cleanup.","Re-dump/backup metadata to verify overall consistency; run `juicefs fsck`/gc to reconcile slice refcounts."],"exampleFix":"// before: silent proceed on undecodable value\nr.decodeDelayedSlices(buf, &ss)\nif len(ss) == 0 { return fmt.Errorf(\"invalid value for delSlices %s: %v\", key, buf) }\n// after (operator remediation, not code): confirm refcounts then\n// redis-cli HDEL <delSlicesKey> <key>\n// and run `juicefs gc` to re-verify slice refs","handlingStrategy":"validation","validationCode":"val, _ := rdb.HGet(ctx, delSlicesKey, key).Result()\nvar ss DelayedSlices\ndecodeDelayedSlices([]byte(val), &ss)\nif len(ss) == 0 { fmt.Printf(\"corrupt delSlices entry %q: %q — reconcile with juicefs gc before cleanup\\n\", key, val) }","typeGuard":null,"tryCatchPattern":"if err := cleanupDelayedSlices(ctx); err != nil && strings.Contains(err.Error(), \"invalid value for delSlices\") {\n    // stop automated cleanup; requires manual reconciliation\n    alertOperator(err)\n}","preventionTips":["Never hand-edit JuiceFS metadata keys in Redis","Verify backups with a full load-test before relying on them","Keep all clients on the same JuiceFS version to avoid encoding drift"],"tags":["redis","corruption","refcount","delayed-slices"],"backgroundTag":"schema-validation-failed","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"}