{"record":{"id":"75c4751f07bce1cb","repo":"AdguardTeam/AdGuardHome","slug":"s-not-supported-on-s-w","errorCode":null,"errorMessage":"%s: not supported on %s: %w","messagePattern":"(.+?): not supported on (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/aghos/os.go","lineNumber":34,"sourceCode":"\t\"runtime\"\n\t\"slices\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/AdguardTeam/golibs/errors\"\n\t\"github.com/AdguardTeam/golibs/osutil/executil\"\n)\n\n// Default file, binary, and directory permissions.\nconst (\n\tDefaultPermDir  fs.FileMode = 0o700\n\tDefaultPermExe  fs.FileMode = 0o700\n\tDefaultPermFile fs.FileMode = 0o600\n)\n\n// Unsupported is a helper that returns a wrapped [errors.ErrUnsupported].\nfunc Unsupported(op string) (err error) {\n\treturn fmt.Errorf(\"%s: not supported on %s: %w\", op, runtime.GOOS, errors.ErrUnsupported)\n}\n\n// SetRlimit sets user-specified limit of how many fd's we can use.\n//\n// See https://github.com/AdguardTeam/AdGuardHome/internal/issues/659.\nfunc SetRlimit(val uint64) (err error) {\n\treturn setRlimit(val)\n}\n\n// HaveAdminRights checks if the current user has root (administrator) rights.\nfunc HaveAdminRights() (bool, error) {\n\treturn haveAdminRights()\n}\n\n// MaxCmdOutputSize is the maximum length of performed shell command output in\n// bytes.\nconst MaxCmdOutputSize = 64 * 1024\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghos/os.go#L16-L52","documentation":"Returned by aghos.Unsupported, this error signals that the requested operation has no implementation on the current platform (runtime.GOOS). It wraps Go 1.21's errors.ErrUnsupported so callers can detect it with errors.Is(err, errors.ErrUnsupported). It is used for OS-specific features like DHCP interface operations, setting rlimits, and changing uid/gid.","triggerScenarios":"Calling checkOtherDHCP, ifaceSetStaticIP, ifaceHasStaticIP, SetRlimit, setGroup, or setUser on a platform where those functions are stubbed out with a call to Unsupported (e.g. setGroup/setUser and rlimit tweaks on Windows, or static-IP interface ops on non-supported Unix variants).","commonSituations":"Building or running AdGuardHome's internal helpers on Windows or an exotic GOOS where syscall-level operations (Setgid, Setuid, RLIMIT, netlink interface manipulation) don't exist; CI matrix builds compiling platform-specific files.","solutions":["Check the value of runtime.GOOS before invoking the platform-specific helper, or gate the call in build-tagged files","Detect it programmatically: if errors.Is(err, errors.ErrUnsupported) { skip or degrade gracefully }","If the feature is required, run on a platform where the operation is implemented (typically Linux/BSD)"],"exampleFix":"// before\nerr := aghos.SetRlimit(65536)\nif err != nil { log.Fatal(err) }\n\n// after\nerr := aghos.SetRlimit(65536)\nif errors.Is(err, errors.ErrUnsupported) {\n    log.Warn(\"rlimit not supported on this OS; skipping\")\n} else if err != nil {\n    log.Fatal(err)\n}","handlingStrategy":"type-guard","validationCode":"if runtime.GOOS == \"windows\" { /* skip rlimit/uid-gid features */ }","typeGuard":"func isUnsupported(err error) bool { return errors.Is(err, errors.ErrUnsupported) }","tryCatchPattern":"err := op()\nif err != nil {\n    if errors.Is(err, errors.ErrUnsupported) { /* degrade gracefully */ return nil }\n    return err\n}","preventionTips":["Gate platform-specific calls behind runtime.GOOS checks or build tags","Always test with errors.Is(err, errors.ErrUnsupported) instead of string matching","Run feature CI on all target platforms"],"tags":["platform-unsupported","go","os","syscall","errors-errunsupported"],"backgroundTag":"unsupported-platform-operation","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}