{"record":{"id":"aa6b75cf73a756cf","repo":"micro/go-micro","slug":"noopwatcher-stopped","errorCode":null,"errorMessage":"noopWatcher stopped","messagePattern":"noopWatcher stopped","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"config/source/noop.go","lineNumber":14,"sourceCode":"package source\n\nimport (\n\t\"errors\"\n)\n\ntype noopWatcher struct {\n\texit chan struct{}\n}\n\nfunc (w *noopWatcher) Next() (*ChangeSet, error) {\n\t<-w.exit\n\n\treturn nil, errors.New(\"noopWatcher stopped\")\n}\n\nfunc (w *noopWatcher) Stop() error {\n\tclose(w.exit)\n\treturn nil\n}\n\n// NewNoopWatcher returns a watcher that blocks on Next() until Stop() is called.\nfunc NewNoopWatcher() (Watcher, error) {\n\treturn &noopWatcher{exit: make(chan struct{})}, nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/config/source/noop.go#L1-L26","documentation":"The noop source's watcher is a placeholder that never produces changes; its Next() blocks on an internal exit channel and only ever returns this error — when Stop() closes the channel. It signals that the watcher was stopped while (or before) a caller waited for the next change.","triggerScenarios":"Calling Stop() on the noopWatcher while another goroutine is blocked in Next(); the surrounding config Watch loop shutting down the watcher, causing the pending Next() to return this error.","commonSituations":"Graceful shutdown of a config watcher; tests that stop watchers to unblock Next(); mistakenly using the noop source in production and wondering why no updates ever arrive.","solutions":["Treat this error as a normal shutdown signal in your watch loop — break out of the loop instead of retrying.","If you need real change notifications, use an actual source (file, envvar, etcd) instead of the noop source.","When shutting down, only Stop() the watcher after cancelling its consumer goroutine, or accept and discard this sentinel error.","In tests, assert on errors.Is/Equal against this message to confirm clean shutdown."],"exampleFix":"// before\nfor {\n    cs, err := w.Next()\n    if err != nil {\n        log.Fatal(err) // wrong: shutdown is expected\n    }\n}\n// after\nfor {\n    cs, err := w.Next()\n    if err != nil {\n        break // watcher stopped; exit loop cleanly\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"cs, err := w.Next()\nif err != nil {\n    return // watcher stopped; exit cleanly\n}","preventionTips":["Treat any error from noopWatcher.Next() as the stop signal","Use a real source if change notifications are required","Coordinate Stop() with the consumer goroutine's lifecycle"],"tags":["config","watcher","shutdown","noop"],"backgroundTag":"watcher-stopped","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}