{"record":{"id":"3b56f1f3b3707ea9","repo":"AdguardTeam/AdGuardHome","slug":"unmarshalling-json-data-into-aghalg-nullbool-bad","errorCode":null,"errorMessage":"unmarshalling json data into aghalg.NullBool: bad value %q","messagePattern":"unmarshalling json data into aghalg\\.NullBool: bad value %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghalg/nullbool.go","lineNumber":61,"sourceCode":"\n// MarshalJSON implements the json.Marshaler interface for NullBool.\nfunc (nb NullBool) MarshalJSON() (b []byte, err error) {\n\treturn []byte(nb.String()), nil\n}\n\n// type check\nvar _ json.Unmarshaler = (*NullBool)(nil)\n\n// UnmarshalJSON implements the json.Unmarshaler interface for *NullBool.\nfunc (nb *NullBool) UnmarshalJSON(b []byte) (err error) {\n\tif len(b) == 0 || bytes.Equal(b, []byte(\"null\")) {\n\t\t*nb = NBNull\n\t} else if bytes.Equal(b, []byte(\"true\")) {\n\t\t*nb = NBTrue\n\t} else if bytes.Equal(b, []byte(\"false\")) {\n\t\t*nb = NBFalse\n\t} else {\n\t\treturn fmt.Errorf(\"unmarshalling json data into aghalg.NullBool: bad value %q\", b)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":43,"sourceCodeEnd":66,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghalg/nullbool.go#L43-L66","documentation":"After successfully rebuilding the configuration manager, Refresh restarts all managed services via s.Start. This error means at least one service (DNS, DHCP, filtering, etc.) failed to initialize with the new configuration. The config was syntactically fine, but a service could not apply it at runtime.","triggerScenarios":"Calling Refresh when the new configuration is valid but a service cannot start under it: e.g. the DNS server cannot bind port 53, a DHCP server cannot bind its interface, or a filtering service cannot download/load its filters.","commonSituations":"Another process (systemd-resolved, dnsmasq, a second instance) already occupies the configured port; configuring a network interface that no longer exists; enabling a service whose data directory is missing or read-only.","solutions":["Check which service failed via the wrapped error and the service logs around the refresh","Verify no other process holds the needed ports (ss -tulpn | grep 53) and stop conflicts","Correct interface/port settings in the configuration and refresh again","Run the service with elevated privileges if binding privileged ports is required"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-check port availability before refresh\nif ln, err := net.Listen(\"tcp\", \":53\"); err != nil { return err } else { ln.Close() }","typeGuard":null,"tryCatchPattern":"if err := svc.Refresh(ctx); err != nil {\n    if strings.Contains(err.Error(), \"restarting services\") {\n        // rollback config or retry after resolving port conflicts\n    }\n}","preventionTips":["Reserve required ports exclusively for this service","Stop conflicting daemons (systemd-resolved, dnsmasq) before configuring","Monitor service logs after every refresh"],"tags":["service-restart","refresh","port-binding","go"],"backgroundTag":"service-start-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}