{"record":{"id":"19c41c1554d9b304","repo":"tailscale/tailscale","slug":"errpolicyclosed","errorCode":"ErrPolicyClosed","errorMessage":"effective policy closed","messagePattern":"effective policy closed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/syspolicy/rsop/resultant_policy.go","lineNumber":23,"sourceCode":"\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"slices\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"tailscale.com/syncs\"\n\t\"tailscale.com/util/syspolicy/internal/loggerx\"\n\t\"tailscale.com/util/syspolicy/setting\"\n\t\"tailscale.com/util/testenv\"\n\n\t\"tailscale.com/util/syspolicy/source\"\n)\n\n// ErrPolicyClosed is returned by [Policy.Reload], [Policy.addSource],\n// [Policy.removeSource] and [Policy.replaceSource] if the policy has been closed.\nvar ErrPolicyClosed = errors.New(\"effective policy closed\")\n\n// The minimum and maximum wait times after detecting a policy change\n// before reloading the policy. This only affects policy reloads triggered\n// by a change in the underlying [source.Store] and does not impact\n// synchronous, caller-initiated reloads, such as when [Policy.Reload] is called.\n//\n// Policy changes occurring within [policyReloadMinDelay] of each other\n// will be batched together, resulting in a single policy reload\n// no later than [policyReloadMaxDelay] after the first detected change.\n// In other words, the effective policy will be reloaded no more often than once\n// every 5 seconds, but at most 15 seconds after an underlying [source.Store]\n// has issued a policy change callback.\n//\n// See [Policy.watchReload].\nvar (\n\tpolicyReloadMinDelay = 5 * time.Second\n\tpolicyReloadMaxDelay = 15 * time.Second\n)","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/util/syspolicy/rsop/resultant_policy.go#L5-L41","documentation":"ErrPolicyClosed is returned by Policy.Reload, addSource, removeSource, and replaceSource when the effective policy has been closed: the RSOP object is torn down and further policy operations are refused via closeCh.","triggerScenarios":"Thrown at util/syspolicy/rsop/resultant_policy.go:23 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Create a new Policy instead of reusing a closed one","Check for closure before invoking policy methods"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}