{"record":{"id":"f6799d2fe53bec53","repo":"netbirdio/netbird","slug":"posture-checks-shouldn-t-be-empty","errorCode":null,"errorMessage":"posture checks shouldn't be empty","messagePattern":"posture checks shouldn't be empty","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"management/server/posture/checks.go","lineNumber":306,"sourceCode":"\t}\n\n\treturn &api.PostureCheck{\n\t\tId:          pc.ID,\n\t\tName:        pc.Name,\n\t\tDescription: &pc.Description,\n\t\tChecks:      checks,\n\t}\n}\n\n// Validate checks the validity of a posture checks.\nfunc (pc *Checks) Validate() error {\n\tif pc.Name == \"\" {\n\t\treturn errors.New(\"posture checks name shouldn't be empty\")\n\t}\n\n\tchecks := pc.GetChecks()\n\tif len(checks) == 0 {\n\t\treturn errors.New(\"posture checks shouldn't be empty\")\n\t}\n\n\tfor _, check := range checks {\n\t\tif err := check.Validate(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc isVersionValid(ver string) bool {\n\tnewVersion, err := version.NewVersion(ver)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tif newVersion != nil {","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/management/server/posture/checks.go#L288-L324","documentation":"Returned by Checks.Validate (management/server/posture/checks.go:306): after the name check passes, GetChecks() must yield at least one concrete check body (for example a version, process, or OS-specific check). A posture check with no actual checks would never evaluate anything, so it is rejected.","triggerScenarios":"POST /api/posture-checks (or PUT) whose checks object is empty, or whose fields all deserialize to nil so GetChecks() returns an empty slice.","commonSituations":"Sending {\"checks\": {}} because the client does not know which check types exist; sending a check under the wrong JSON key so it is silently ignored during unmarshalling; building the payload from a config schema that drifted from the server version.","solutions":["Include at least one real check body under its correct key, e.g. checks.nb_version_check, checks.process_check, or the OS-specific variants","Verify the field name against the API schema (shared/management/http/api) for the server version you call"],"exampleFix":"// before\n{ \"name\": \"agent\", \"checks\": {} }\n\n// after\n{ \"name\": \"agent\", \"checks\": { \"nb_version_check\": { \"min_version\": \"0.50.0\" } } }","handlingStrategy":"validation","validationCode":"// Mirror GetChecks(): at least one check body must be non-nil\nhasCheck := req.Checks.NBVersionCheck != nil || req.Checks.ProcessCheck != nil /* ... OS variants ... */\nif !hasCheck {\n    return errors.New(\"at least one concrete check (e.g. nb_version_check) is required\")\n}","typeGuard":null,"tryCatchPattern":"_, err := postureAPI.CreateCheck(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"posture checks shouldn't be empty\") {\n    // the checks key was empty or unrecognized; fix payload keys, not the retry\n}","preventionTips":["Pin your client model to the server's openapi.yml so unknown check keys fail locally, not silently on the server","Never send {\"checks\": {}}; if no check is configured, do not create the posture check at all","Unit-test payload marshalling for each check type you use"],"tags":["management","api","posture","validation"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}