{"record":{"id":"e8e2984e98fe6530","repo":"AdguardTeam/AdGuardHome","slug":"end-s-is-greater-than-s","errorCode":null,"errorMessage":"end %s is greater than %s","messagePattern":"end (.+?) is greater than (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/schedule/schedule.go","lineNumber":315,"sourceCode":"\t// or equal to zero and less than or equal to 24h.\n\tend time.Duration\n}\n\n// validate returns the day range validation errors, if any.\nfunc (r dayRange) validate() (err error) {\n\tswitch {\n\tcase r == dayRange{}:\n\t\treturn nil\n\tcase r.start < 0:\n\t\treturn fmt.Errorf(\"start %s is negative\", r.start)\n\tcase r.end < 0:\n\t\treturn fmt.Errorf(\"end %s is negative\", r.end)\n\tcase r.start >= r.end:\n\t\treturn fmt.Errorf(\"start %s is greater or equal to end %s\", r.start, r.end)\n\tcase r.start >= maxDayRange:\n\t\treturn fmt.Errorf(\"start %s is greater or equal to %s\", r.start, maxDayRange)\n\tcase r.end > maxDayRange:\n\t\treturn fmt.Errorf(\"end %s is greater than %s\", r.end, maxDayRange)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// contains returns true if start <= offset < end, where offset is the time\n// duration from the beginning of the day.\nfunc (r *dayRange) contains(offset time.Duration) (ok bool) {\n\treturn r.start <= offset && offset < r.end\n}\n\n// toDayConfigJSON returns nil if the day range is empty, otherwise returns\n// initialized JSON configuration of the day range.\nfunc (r dayRange) toDayConfigJSON() (j *dayConfigJSON) {\n\tif (r == dayRange{}) {\n\t\treturn nil\n\t}\n","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/schedule/schedule.go#L297-L333","documentation":"The schedule validator rejects a range whose end value exceeds maxDayRange, i.e. the range extends past the end of the day. It surfaces from UnmarshalJSON/UnmarshalYAML when the schedule is parsed.","triggerScenarios":"Unmarshaling a schedule where end > maxDayRange (e.g. end offset larger than 24 hours / the day boundary the library enforces).","commonSituations":"Overnight ranges written as end > 24h instead of being split into two ranges; unit mismatches (minutes vs hours) in config files.","solutions":["Split ranges crossing midnight into two ranges (e.g. 22:00–24:00 and 00:00–06:00)","Verify the end value's unit matches the library's expectation and is <= maxDayRange","Add a config pre-check that clamps or rejects out-of-day ranges"],"exampleFix":"// before\n{\"start\": \"22:00\", \"end\": \"30:00\"}\n// after\n[{\"start\": \"22:00\", \"end\": \"24:00\"}, {\"start\": \"00:00\", \"end\": \"06:00\"}]","handlingStrategy":"validation","validationCode":"const day = 24 * time.Hour\nif r.End > day { return fmt.Errorf(\"end %s exceeds day; split overnight ranges\", r.End) }","typeGuard":"func withinDay(d time.Duration) bool { return d <= 24*time.Hour }","tryCatchPattern":"if err := yaml.Unmarshal(cfg, &sched); err != nil { return fmt.Errorf(\"schedule config: %w\", err) }","preventionTips":["Split overnight ranges at midnight","Keep units consistent across start/end","Automated config validation before unmarshal"],"tags":["schedule","config-validation","time-range"],"backgroundTag":"config-validation-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}