{"record":{"id":"2d96ab065c121b8b","repo":"nats-io/nats-server","slug":"onreload-sort-or-explicitly-skip-type-s","errorCode":null,"errorMessage":"OnReload, sort or explicitly skip type: %s","messagePattern":"OnReload, sort or explicitly skip type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/reload.go","lineNumber":1574,"sourceCode":"\tcase []*url.URL:\n\t\tslices.SortFunc(value, func(i, j *url.URL) int { return cmp.Compare(i.String(), j.String()) })\n\tcase []string:\n\t\tslices.Sort(value)\n\tcase []*jwt.OperatorClaims:\n\t\tslices.SortFunc(value, func(i, j *jwt.OperatorClaims) int { return cmp.Compare(i.Issuer, j.Issuer) })\n\tcase GatewayOpts:\n\t\tslices.SortFunc(value.Gateways, func(i, j *RemoteGatewayOpts) int { return cmp.Compare(i.Name, j.Name) })\n\tcase WebsocketOpts:\n\t\tslices.Sort(value.AllowedOrigins)\n\tcase string, bool, uint8, uint16, uint64, int, int32, int64, time.Duration, float64, nil, LeafNodeOpts, ClusterOpts, *tls.Config, PinnedCertSet,\n\t\t*URLAccResolver, *MemAccResolver, *DirAccResolver, *CacheDirAccResolver, Authentication, MQTTOpts, jwt.TagList,\n\t\t*OCSPConfig, map[string]string, map[string]bool, JSLimitOpts, StoreCipher, *OCSPResponseCacheConfig, *ProxiesConfig, WriteTimeoutPolicy:\n\t\t// explicitly skipped types\n\tcase *AuthCallout:\n\tcase JSTpmOpts:\n\tdefault:\n\t\t// this will fail during unit tests\n\t\treturn fmt.Errorf(\"OnReload, sort or explicitly skip type: %s\",\n\t\t\treflect.TypeOf(value))\n\t}\n\treturn nil\n}\n\n// diffOptions returns a slice containing options which have been changed. If\n// an option that doesn't support hot-swapping is changed, this returns an\n// error.\nfunc (s *Server) diffOptions(newOpts *Options) ([]option, error) {\n\tvar (\n\t\toldOpts   = s.getOpts()\n\t\toldConfig = reflect.ValueOf(oldOpts).Elem()\n\t\tnewConfig = reflect.ValueOf(newOpts).Elem()\n\t\tdiffOpts  = []option{}\n\t\tskipTKeys = len(oldOpts.TrustedOperators) > 0 && len(oldOpts.TrustedKeys) > 0\n\n\t\t// Need to keep track of whether JS is being disabled\n\t\t// to prevent changing limits at runtime.","sourceCodeStart":1556,"sourceCodeEnd":1592,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/reload.go#L1556-L1592","documentation":"applyOptions/diff machinery switches over every option type changed during reload; the default branch rejects types that were not sorted (mapped to a diff option) or explicitly skipped. This is a developer-facing guard so newly added config fields must be handled in the reload diff switch.","triggerScenarios":"A new options field's type (e.g. a custom struct) is changed at runtime and passed to the reload diff switch without a case or an explicit skip entry, causing this error during Reload().","commonSituations":"Contributors adding a new config option to server Options without updating server/reload.go's type switch; custom forks with extended Options fields being hot-reloaded.","solutions":["Add a case for the missing type in the reload diff switch in server/reload.go, mapping it to an appropriate option.","Add the type to the explicitly-skipped case list if the field does not support hot reload.","Restart the server instead of reloading if you cannot modify the code handling the new option type."],"exampleFix":"// before\ndefault:\n    return fmt.Errorf(\"OnReload, sort or explicitly skip type: %s\", reflect.TypeOf(value))\n// after\ncase *MyNewOptionType:\n    diffOpts = append(diffOpts, &myNewOption{newValue: value.(*MyNewOptionType)})","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := srv.Reload(); err != nil {\n    if strings.Contains(err.Error(), \"OnReload, sort or explicitly skip type\") {\n        log.Fatalf(\"new option type not handled for reload: %v\", err) // fall back to restart\n    }\n}","preventionTips":["When adding Options fields, always update the reload type switch in server/reload.go.","Run the reload unit tests (the switch is designed to fail there) in CI.","Explicitly skip types that must not support hot reload."],"tags":["reload","developer-guard","type-switch"],"backgroundTag":"unhandled-type-switch-case","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}