{"record":{"id":"758b8ecf125ee2cc","repo":"ginuerzh/gost","slug":"none-node-available","errorCode":null,"errorMessage":"none node available","messagePattern":"none node available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"selector.go","lineNumber":18,"sourceCode":"package gost\n\nimport (\n\t\"errors\"\n\t\"math/rand\"\n\t\"net\"\n\t\"sort\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/go-log/log\"\n)\n\nvar (\n\t// ErrNoneAvailable indicates there is no node available.\n\tErrNoneAvailable = errors.New(\"none node available\")\n)\n\n// NodeSelector as a mechanism to pick nodes and mark their status.\ntype NodeSelector interface {\n\tSelect(nodes []Node, opts ...SelectOption) (Node, error)\n}\n\ntype defaultSelector struct {\n}\n\nfunc (s *defaultSelector) Select(nodes []Node, opts ...SelectOption) (Node, error) {\n\tsopts := SelectOptions{}\n\tfor _, opt := range opts {\n\t\topt(&sopts)\n\t}\n\n\tfor _, filter := range sopts.Filters {\n\t\tnodes = filter.Filter(nodes)","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/selector.go#L1-L36","documentation":"ErrNoneAvailable is returned by Select when the candidate node list is empty after filtering — there is no node to pick. It is the selector's canonical 'no backend available' signal, exported so callers can compare against it directly.","triggerScenarios":"Calling NodeSelector.Select with a nil/empty nodes slice (or all nodes filtered out as dead/unreachable), e.g. selector.Select(nil) as in the test.","commonSituations":"All backends marked down by the selector's status tracking, an empty registry (no nodes registered), or a misconfigured route matching no nodes.","solutions":["Check backend health/registration — ensure at least one node is up and registered","Clear failed-node marks or wait for node status recovery/retry policy to re-admit nodes","Add a fallback: return a default node or propagate the error to trigger another route","Verify the request metadata isn't filtering out all nodes"],"exampleFix":"// before\nnode, err := selector.Select(nodes)\n// after\nnode, err := selector.Select(nodes)\nif err == selector.ErrNoneAvailable {\n    // no backends: fallback or surface a clear 503\n    return errors.New(\"no upstream nodes available\")\n}","handlingStrategy":"try-catch","validationCode":"if len(nodes) == 0 {\n    return errors.New(\"no candidate nodes registered\")\n}","typeGuard":null,"tryCatchPattern":"node, err := selector.Select(nodes)\nif err == selector.ErrNoneAvailable {\n    // all backends down: fail fast or retry later\n    return errors.New(\"no upstream available\")\n}","preventionTips":["Monitor node registry so empty backends alert early","Configure retry/recovery so failed nodes rejoin","Add fallback routing when all nodes are unavailable"],"tags":["selector","load-balancing","no-backend"],"backgroundTag":"no-nodes-available","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}