{"record":{"id":"5cb97667b1ae1fb3","repo":"juicedata/juicefs","slug":"create-object-sorter-s","errorCode":null,"errorMessage":"create object sorter: %s","messagePattern":"create object sorter: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/gc_external.go","lineNumber":122,"sourceCode":"\t})\n\tif err != nil {\n\t\treturn nil, nil, errors.Errorf(\"create meta sorter: %s\", err)\n\t}\n\n\tobjSorter, err := extsort.New(ctx, extsort.Config{\n\t\tWorkDir:  extSortDir,\n\t\tName:     \"gc-object\",\n\t\tThreads:  threads,\n\t\tChecksum: true,\n\t}, extsort.Codec[gcObjectRecord]{\n\t\tFromBytes: gcObjectRecordFromBytes,\n\t\tToBytes:   gcObjectRecordToBytes,\n\t\tCompare:   compareGcObjectRecord,\n\t})\n\tif err != nil {\n\t\tmetaSorter.CloseInput()\n\t\t_ = metaSorter.Done()\n\t\treturn nil, nil, errors.Errorf(\"create object sorter: %s\", err)\n\t}\n\treturn metaSorter, objSorter, nil\n}\n\nfunc scanGcMetaRecords(c meta.Context, m meta.Meta, output chan<- gcMetaRecord, metaSliceSpin *utils.Bar) error {\n\tst := m.ScanSlices(c, &meta.ScanSlicesOption{ScanPending: true}, func(ino meta.Ino, s meta.Slice) error {\n\t\tselect {\n\t\tcase <-c.Done():\n\t\t\treturn c.Err()\n\t\tdefault:\n\t\t}\n\t\tmetaSliceSpin.Increment()\n\t\tvar state uint8\n\t\tswitch ino {\n\t\tcase 0:\n\t\t\tstate = gcStatePending\n\t\tcase 1:\n\t\t\tstate = gcStateTrash","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/gc_external.go#L104-L140","documentation":"Wraps a failure from extsort.New when constructing the second (object-record) external sorter used by `juicefs gc --sort`. extsort.New fails when it cannot prepare its work directory or spawn its I/O resources (e.g. WorkDir is not writable/creatable, or invalid Threads config). The already-created meta sorter is closed and torn down before returning.","triggerScenarios":"Running `juicefs gc` in external-sort mode where extSortDir (the --sort-dir) is unwritable, does not exist and cannot be created, is on a full filesystem, or the extsort config (WorkDir/Name/Threads) is invalid such that extsort.New returns an error for the gc-object sorter after the gc-meta sorter succeeded.","commonSituations":"gc run in a container whose sort directory is read-only or on a tmpfs that ran out of space; --sort-dir pointing to a path the user cannot write; disk full on the sort volume; extremely small thread/resource limits.","solutions":["Check the wrapped cause message for the underlying extsort failure (usually mkdir/permission/disk-space)","Verify the --sort-dir path exists and is writable by the running user (e.g. `touch <dir>/test && rm <dir>/test`)","Free space on the filesystem backing the sort directory or pick another directory with space","Re-run `juicefs gc` once the directory is writable"],"exampleFix":"// before\njuicefs gc --sort-dir /mnt/ro-volume/sort sqlite3://test.db\n// after\nmkdir -p /var/tmp/jfs-gc-sort && chmod u+w /var/tmp/jfs-gc-sort\njuicefs gc --sort-dir /var/tmp/jfs-gc-sort sqlite3://test.db","handlingStrategy":"validation","validationCode":"if fi, err := os.Stat(extSortDir); err != nil || !fi.IsDir() { return fmt.Errorf(\"sort dir unavailable: %w\", err) }\nif f, err := os.CreateTemp(extSortDir, \".probe\"); err != nil { return err } else { f.Close(); os.Remove(f.Name()) }","typeGuard":null,"tryCatchPattern":"if _, _, err := newGcExternalSorters(ctx, dir, threads); err != nil {\n\tlog.Printf(\"gc aborted: %v — check sort dir %s is writable and has free space\", err, dir)\n}","preventionTips":["Provision the --sort-dir on a writable volume with ample free space","Probe writability before launching long gc runs","Run gc as a user with write access to the sort directory"],"tags":["gc","external-sort","filesystem","io"],"backgroundTag":"file-write-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"}