{"record":{"id":"45cf1e88e9a6deff","repo":"AdguardTeam/AdGuardHome","slug":"removing-q-w","errorCode":null,"errorMessage":"removing %q: %w","messagePattern":"removing %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghos/fswatcher.go","lineNumber":188,"sourceCode":"\t}\n\n\tif !names.Has(name) {\n\t\t// Name is not tracked.\n\t\treturn nil\n\t}\n\n\tnames.Delete(name)\n\tif names.Len() > 0 {\n\t\t// Some files are still tracked in the directory.\n\t\treturn nil\n\t}\n\n\t// No more files tracked in the directory, unwatch it.\n\tdelete(w.files, dirName)\n\n\terr = w.watcher.Remove(dirName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"removing %q: %w\", dirName, err)\n\t}\n\n\treturn nil\n}\n\n// handleEvents notifies about the received file system's event if needed.  It\n// is intended to be used as a goroutine.\nfunc (w *OSWatcher) handleEvents(ctx context.Context) {\n\tdefer slogutil.RecoverAndLog(ctx, w.logger)\n\n\tdefer close(w.events)\n\n\tch := w.watcher.Events\n\tfor e := range ch {\n\t\tif !w.isTrackedEvent(e) {\n\t\t\tcontinue\n\t\t}\n","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghos/fswatcher.go#L170-L206","documentation":"dayRange.validate requires start to be strictly earlier than end; an inverted or zero-length range yields 'start <s> is greater or equal to end <e>'. This catches reversed times and empty intervals during JSON/YAML schedule parsing.","triggerScenarios":"A schedule day where start equals end or start is after end, e.g. start \"22:00\" end \"06:00\" (attempting overnight ranges, which the schema forbids) or start == end.","commonSituations":"Users trying to express overnight schedules crossing midnight; swapped start/end in hand-edited configs; importers mapping 'from/to' fields in the wrong order.","solutions":["Split overnight ranges into two entries: one ending at 24:00 and one starting at 00:00","Swap start/end if they are merely reversed","Ensure start < end strictly (equal values are rejected)","Model full-day as start 00:00 end 24:00 (maxDayRange) if supported"],"exampleFix":"// before\n{\"start\": \"22:00\", \"end\": \"06:00\"}\n// after\n{\"sun\": {\"start\": \"00:00\", \"end\": \"06:00\"},\n \"sat\": {\"start\": \"22:00\", \"end\": \"24:00\"}}","handlingStrategy":"validation","validationCode":"if start >= end { return fmt.Errorf(\"inverted range %v-%v\", start, end) }","typeGuard":"func isValidOrder(s, e time.Duration) bool { return s < e }","tryCatchPattern":"if err := unmarshalSchedule(data); err != nil && strings.Contains(err.Error(), \"greater or equal to end\") {\n    // swap or split overnight range, retry\n}","preventionTips":["Split overnight schedules at midnight into two entries","Validate order in generators before writing config","Treat equal start/end as invalid, not as empty"],"tags":["schedule","validation","time","config","go"],"backgroundTag":"config-validation-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}