AdguardTeam/AdGuardHome · error

checking file %q: %w

Error message

checking file %q: %w

What it means

dayRange.validate rejects any schedule range whose start is a negative duration — 'start <val> is negative'. Only the empty range (zero start and end, meaning disabled) is allowed to bypass the checks, so a nonzero negative start always fails.

Source

Thrown at internal/aghos/fswatcher.go:124

func (w *OSWatcher) Shutdown(_ context.Context) (err error) {
	return errors.Annotate(w.watcher.Close(), "%s: %w", osWatcherPref)
}

// Events implements the [FSWatcher] interface for *OSWatcher.
func (w *OSWatcher) Events() (e <-chan Event) {
	return w.events
}

// Add implements the [FSWatcher] interface for *OSWatcher.  It's safe for
// concurrent use.
//
// TODO(e.burkov):  Make it accept non-existing files to detect it's creating.
func (w *OSWatcher) Add(name string) (err error) {
	defer func() { err = errors.Annotate(err, "%s: %w", osWatcherPref) }()

	fi, err := os.Stat(name)
	if err != nil {
		return fmt.Errorf("checking file %q: %w", name, err)
	}

	// Watch the directory and filter the events by the file name, since the
	// common recomendation to the fsnotify package is to watch the directory
	// instead of the file itself.
	//
	// See https://pkg.go.dev/github.com/fsnotify/fsnotify@v1.7.0#readme-watching-a-file-doesn-t-work-well.
	dirName := name
	if !fi.IsDir() {
		dirName = filepath.Dir(name)
	}

	w.filesMu.Lock()
	defer w.filesMu.Unlock()

	names := w.files[dirName]
	if names == nil {
		names = container.NewMapSet[string]()

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Clamp start to zero or a positive minute-aligned time
  2. Fix the timezone/conversion logic that produced the negative value
  3. Leave the day absent/empty rather than negative to disable it
  4. Re-validate the schedule after correction

Example fix

// before
{"start": "-01:00", "end": "02:00"}
// after
{"start": "01:00", "end": "02:00"}
Defensive patterns

Strategy: validation

Validate before calling

if start < 0 { start = 0 }

Type guard

func isNonNegative(d time.Duration) bool { return d >= 0 }

Try / catch

if err := unmarshalSchedule(data); err != nil && strings.Contains(err.Error(), "is negative") {
    // clamp to zero or omit day, retry
}

Prevention

When it happens

Trigger: A weekly schedule day with a negative start value, e.g. "-01:00" or a negative millisecond count, during JSON/YAML unmarshalling.

Common situations: Timezone conversions producing negative offsets; hand-editing mistakes with minus signs; scripts subtracting durations without clamping at zero.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/d87406562a17e2a2. Report an issue: GitHub.