{"record":{"id":"6f68ebd58e15c87d","repo":"syncthing/syncthing","slug":"restart-after-db-reset-initiated-by-rest-api","errorCode":null,"errorMessage":"restart after db reset initiated by rest API","messagePattern":"restart after db reset initiated by rest API","errorType":"console","errorClass":"svcutil.FatalErr","httpStatus":null,"severity":"info","filePath":"lib/api/api.go","lineNumber":1016,"sourceCode":"\t\t// Reset all folders.\n\t\tfor folder := range s.cfg.Folders() {\n\t\t\tif err := s.model.ResetFolder(folder); err != nil {\n\t\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\ts.flushResponse(`{\"ok\": \"resetting database\"}`, w)\n\t} else {\n\t\t// Reset a specific folder, assuming it's supposed to exist.\n\t\tif err := s.model.ResetFolder(folder); err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\ts.flushResponse(`{\"ok\": \"resetting folder `+folder+`\"}`, w)\n\t}\n\n\ts.fatal(&svcutil.FatalErr{\n\t\tErr:    errors.New(\"restart after db reset initiated by rest API\"),\n\t\tStatus: svcutil.ExitRestart,\n\t})\n}\n\nfunc (s *service) postSystemShutdown(w http.ResponseWriter, _ *http.Request) {\n\ts.flushResponse(`{\"ok\": \"shutting down\"}`, w)\n\ts.fatal(&svcutil.FatalErr{\n\t\tErr:    errors.New(\"shutdown initiated by rest API\"),\n\t\tStatus: svcutil.ExitSuccess,\n\t})\n}\n\nfunc (*service) flushResponse(resp string, w http.ResponseWriter) {\n\tw.Write([]byte(resp + \"\\n\"))\n\tf := w.(http.Flusher)\n\tf.Flush()\n}\n","sourceCodeStart":998,"sourceCodeEnd":1034,"githubUrl":"https://github.com/syncthing/syncthing/blob/058bcd7334839663cf569501d3ac539034d45cb5/lib/api/api.go#L998-L1034","documentation":"This is not a failure: it is a deliberately constructed sentinel error passed to s.fatal() by the REST handler for POST /rest/system/reset after the handler has flushed a success response. It instructs the supervised process to exit with svcutil.ExitRestart so the supervisor restarts Syncthing and the just-wiped or reset database is reopened cleanly. Any caller of the reset endpoint should expect the process to terminate by design.","triggerScenarios":"POST /rest/system/reset (with or without ?folder=...) reaching the end of the handler: after ResetAll or model.ResetFolder succeeds and '{\"ok\": \"resetting...\"}' has been flushed, s.fatal(&svcutil.FatalErr{Err: errors.New(\"restart after db reset initiated by rest API\"), Status: svcutil.ExitRestart}) is invoked unconditionally.","commonSituations":"Automation or a GUI script calling the reset endpoint and then being surprised that subsequent REST calls fail because the process exited; expecting an error body instead of the flushed ok JSON followed by process exit.","solutions":["Treat the flushed '{\"ok\": \"resetting...\"}' response as the success signal and stop making further API calls until the service restarts.","Have your supervision wrapper (systemd, docker restart policy, syncthing's own -resume or supervisor) restart the process on the ExitRestart exit status.","If you only wanted to reset one folder, pass ?folder=<id> and still expect the restart, since the handler always calls s.fatal with ExitRestart.","Back up index databases before calling reset if you might need the data; reset is destructive."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before calling reset, confirm you really want a restart:\n// POST /rest/system/reset always ends with the process exiting (ExitRestart).\n// Validate preconditions (backup taken, no in-flight transfers) first.\nresp, err := http.Post(apiURL+\"/rest/system/reset\", \"\", nil)\n// After reading '{\"ok\": \"resetting...\"}', stop calling the API until restart completes.","typeGuard":null,"tryCatchPattern":"// Not applicable: this is a deliberate process-exit sentinel, not a catchable\n// API error. The response body '{\"ok\": \"resetting database\"}' is the success signal.","preventionTips":["Treat POST /rest/system/reset as destructive and terminal for the current process; script the follow-up as wait-for-restart.","Back up the index database before resetting.","Wrap automation with a readiness poll (e.g. GET /rest/system/version) after the reset instead of immediate further calls."],"tags":["rest-api","lifecycle","restart","database","syncthing"],"backgroundTag":null,"analyzedSha":"058bcd7334839663cf569501d3ac539034d45cb5","analyzedAt":"2026-08-15T07:53:43.174Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}