{"record":{"id":"25a0afba33de4925","repo":"juicedata/juicefs","slug":"json-s-25a0af","errorCode":null,"errorMessage":"json: %s","messagePattern":"json: %s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql.go","lineNumber":633,"sourceCode":"func (m *dbMeta) doInit(format *Format, force bool) error {\n\tif err := m.syncAllTables(); err != nil {\n\t\treturn err\n\t}\n\tvar s = setting{Name: \"format\"}\n\tvar ok bool\n\terr := m.simpleTxn(Background(), func(ses *xorm.Session) (err error) {\n\t\tok, err = ses.Get(&s)\n\t\treturn err\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif ok {\n\t\tvar old Format\n\t\terr = json.Unmarshal([]byte(s.Value), &old)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"json: %s\", err)\n\t\t}\n\t\tif !old.DirStats && format.DirStats {\n\t\t\t// remove dir stats as they are outdated\n\t\t\terr = m.txn(func(s *xorm.Session) error {\n\t\t\t\t_, err := s.Where(\"TRUE\").Delete(new(dirStats))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tm.genLog(Background(), s, time.Now().UnixNano(), \"INIT_ENABLE_DIRSTATS()\")\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"drop table dirStats\")\n\t\t\t}\n\t\t}\n\t\tif !old.UserGroupQuota && format.UserGroupQuota {\n\t\t\t// remove user group quota as they are outdated\n\t\t\terr = m.txn(func(s *xorm.Session) error {","sourceCodeStart":615,"sourceCodeEnd":651,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L615-L651","documentation":"When a volume is re-formatted (the format setting already exists), the stored format JSON is unmarshaled to compare old vs new settings. If the stored 'format' setting is not valid JSON, json.Unmarshal fails and the error is wrapped as 'json: %s'.","triggerScenarios":"juicefs format with an existing volume whose jfs.format setting row in the setting table is corrupted, truncated, or was written by a incompatible/older tool.","commonSituations":"Manual editing of the settings table; partial write from a crashed format; restoring metadata from a damaged backup; someone overwrote the setting value.","solutions":["Inspect the setting row: SELECT value FROM <prefix>setting WHERE name='format'; and check for corruption","Restore the volume format from a known-good backup (juicefs dump metadata output)","Delete the corrupted setting row and re-run juicefs format with the original format options","Recover from juicefs backup metadata if available"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before re-formatting, verify the stored format is valid JSON\nrow := db.QueryRow(\"SELECT value FROM setting WHERE name='format'\")\nvar v string; row.Scan(&v)\nvar f map[string]any\nif json.Unmarshal([]byte(v), &f) != nil { /* restore from backup before formatting */ }","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil { log.Fatalf(\"format corrupt: %v\", r) }\n}()","preventionTips":["Never hand-edit metadata tables","Keep regular juicefs dump backups","Restore metadata only from complete backups"],"tags":["json","unmarshal","corruption","sql","format"],"backgroundTag":"json-unmarshal-failed","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"}