{"record":{"id":"1a34c834769fb37a","repo":"netbirdio/netbird","slug":"parse-service-params-s-w","errorCode":null,"errorMessage":"parse service params %s: %w","messagePattern":"parse service params (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/service_params.go","lineNumber":59,"sourceCode":"\treturn filepath.Join(configs.StateDir, serviceParamsFile)\n}\n\n// loadServiceParams reads saved service parameters from disk.\n// Returns nil with no error if the file does not exist.\nfunc loadServiceParams() (*serviceParams, error) {\n\tpath := serviceParamsPath()\n\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, nil //nolint:nilnil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"read service params %s: %w\", path, err)\n\t}\n\n\tvar params serviceParams\n\tif err := json.Unmarshal(data, &params); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse service params %s: %w\", path, err)\n\t}\n\n\treturn &params, nil\n}\n\n// saveServiceParams writes current service parameters to disk atomically\n// with restricted permissions.\nfunc saveServiceParams(params *serviceParams) error {\n\tpath := serviceParamsPath()\n\tif err := util.WriteJsonWithRestrictedPermission(context.Background(), path, params); err != nil {\n\t\treturn fmt.Errorf(\"save service params: %w\", err)\n\t}\n\treturn nil\n}\n\n// currentServiceParams captures the current state of all package-level\n// variables into a serviceParams struct.\nfunc currentServiceParams() *serviceParams {","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/service_params.go#L41-L77","documentation":"service.json exists but json.Unmarshal rejected it as a serviceParams document, so the file is truncated/corrupted or shaped differently than the schema expects (for example a field stored as the wrong JSON type).","triggerScenarios":"A crash or kill during an older non-atomic write left a partial file; manual editing introduced a syntax error; a version change altered a field type (log_files expected as array).","commonSituations":"Power loss or forced reboot mid-install; hand-editing service.json to tweak the log level; downgrading the CLI over a newer service.json.","solutions":["Run netbird service reset-params to delete the bad file; the next install uses defaults","Or fix the JSON syntax / restore from backup","Pass settings explicitly on the next install (--log-level etc.) so the file is rewritten cleanly","If it recurs, ensure two installs never run concurrently and check disk health"],"exampleFix":"# after a parse failure, discard and rebuild\nnetbird service reset-params\nnetbird service install --log-level debug","handlingStrategy":"fallback","validationCode":"if data, err := os.ReadFile(serviceParamsPath()); err == nil {\n\tvar probe serviceParams\n\tif jerr := json.Unmarshal(data, &probe); jerr != nil {\n\t\t_ = os.Rename(serviceParamsPath(), serviceParamsPath()+\".corrupt\")\n\t\t// proceed with defaults\n\t}\n}","typeGuard":"func isCorruptParamsJSON(err error) bool {\n\tvar syn *json.SyntaxError\n\tvar typ *json.UnmarshalTypeError\n\treturn errors.As(err, &syn) || errors.As(err, &typ)\n}","tryCatchPattern":"if err := json.Unmarshal(data, &params); err != nil {\n\tif isCorruptParamsJSON(err) {\n\t\t_ = os.Remove(path) // or rename to .corrupt; defaults are re-derived on next install\n\t\treturn nil, nil\n\t}\n\treturn fmt.Errorf(\"parse service params %s: %w\", path, err)\n}","preventionTips":["Never hand-edit service.json; use install flags instead","Keep a copy of service.json before upgrades","Run netbird service reset-params when behavior after an upgrade looks stale"],"tags":["service","state","json","corruption","go"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}