{"record":{"id":"63ae4e510437e460","repo":"juanfont/headscale","slug":"saving-node-w","errorCode":null,"errorMessage":"saving node: %w","messagePattern":"saving node: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"hscontrol/state/state.go","lineNumber":556,"sourceCode":"\t\tlog.Warn().\n\t\t\tEmbedObject(node).\n\t\t\tBool(\"is_ephemeral\", node.IsEphemeral()).\n\t\t\tMsg(\"Node no longer exists in NodeStore, skipping database persist to prevent race condition\")\n\n\t\treturn types.NodeView{}, fmt.Errorf(\"%w: %d\", ErrNodeNotInNodeStore, node.ID())\n\t}\n\n\tnodePtr := fresh.AsStruct()\n\n\t// Explicitly select all node columns so GORM includes nil/zero-value\n\t// fields (e.g. UserID=nil when converting a user-owned node to tagged).\n\t// Omit \"Expiry\" here: expiry is only updated through explicit\n\t// SetNodeExpiry calls or re-registration, not during MapRequest updates.\n\terr := s.db.DB.Select(nodeUpdateColumns).Omit(\"Expiry\").Updates(nodePtr).Error\n\ts.persistMu.Unlock()\n\n\tif err != nil {\n\t\treturn types.NodeView{}, fmt.Errorf(\"saving node: %w\", err)\n\t}\n\n\treturn fresh, nil\n}\n\n// persistNodeToDB saves the given node state to the database and refreshes the\n// policy manager. The exact row written comes from [NodeStore]; see\n// [State.persistNodeRowToDB].\nfunc (s *State) persistNodeToDB(node types.NodeView) (types.NodeView, change.Change, error) {\n\tfresh, err := s.persistNodeRowToDB(node)\n\tif err != nil {\n\t\treturn types.NodeView{}, change.Change{}, err\n\t}\n\n\t// Check if policy manager needs updating\n\tc, err := s.updatePolicyManagerNodes()\n\tif err != nil {\n\t\treturn fresh, change.Change{}, fmt.Errorf(\"updating policy manager after node save: %w\", err)","sourceCodeStart":538,"sourceCodeEnd":574,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/hscontrol/state/state.go#L538-L574","documentation":"Error \"saving node: %w\" thrown in juanfont/headscale.","triggerScenarios":"Thrown at hscontrol/state/state.go:556 when the library encounters an invalid state.","commonSituations":"Persisting the node failed. Check database availability and that the node's fields (name, keys) are valid and unique.","solutions":["Inspect the wrapped error for the underlying cause and correct the failing condition (saving node); retry the operation after fixing the input, configuration, or environment."],"exampleFix":"Inspect the wrapped error for the underlying cause and correct the failing condition (saving node); retry the operation after fixing the input, configuration, or environment.","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}