{"record":{"id":"bcfb85a5d61edb55","repo":"txthinking/brook","slug":"black-hole","errorCode":null,"errorMessage":"black hole","messagePattern":"black hole","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/dialwithnic/dialwithnic.go","lineNumber":64,"sourceCode":"\t\t\t\treturn v.(*net.IPNet).IP, nil\n\t\t\t}\n\t\t}\n\t\treturn nil, errors.New(\"no ipv6 from nic\")\n\t}\n\tif v46 == \"4\" {\n\t\tfor _, v := range addrs {\n\t\t\tif v.(*net.IPNet).IP.IsGlobalUnicast() && !v.(*net.IPNet).IP.IsPrivate() && v.(*net.IPNet).IP.To4() != nil {\n\t\t\t\treturn v.(*net.IPNet).IP, nil\n\t\t\t}\n\t\t}\n\t\tfor _, v := range addrs {\n\t\t\tif v.(*net.IPNet).IP.IsGlobalUnicast() && v.(*net.IPNet).IP.IsPrivate() && v.(*net.IPNet).IP.To4() != nil {\n\t\t\t\treturn v.(*net.IPNet).IP, nil\n\t\t\t}\n\t\t}\n\t\treturn nil, errors.New(\"no ipv4 from nic\")\n\t}\n\treturn nil, errors.New(\"black hole\")\n}\n\nfunc (p *DialWithNIC) TouchBrook() {\n\tbrook.DialTCP = func(network string, laddr, raddr string) (net.Conn, error) {\n\t\tvar la, ra *net.TCPAddr\n\t\tif laddr != \"\" {\n\t\t\tvar err error\n\t\t\tla, err = net.ResolveTCPAddr(network, laddr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\ta, err := brook.Resolve(network, raddr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tra = a.(*net.TCPAddr)\n\t\tif la == nil {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/txthinking/brook/blob/5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8/plugins/dialwithnic/dialwithnic.go#L46-L82","documentation":"This is the fallthrough at the end of the IP method: if v46 is neither \"6\" nor \"4\", none of the address-scanning branches run and the method returns this error. It indicates an invalid v46 argument value — the caller asked for neither IPv4 nor IPv6, so the library has no address-selection strategy and returns the sentinel 'black hole'.","triggerScenarios":"Calling IP with any v46 value other than the exact strings \"6\" or \"4\" — e.g. \"\", \"v6\", \"ipv6\", \"IPv4\", or a value read from config that was not normalized. Note it is case-sensitive: \"V6\"/\"V4\" also land here.","commonSituations":"v46 read from a config file or environment variable with unexpected casing or whitespace; an unset/empty config value passed straight through; typos like \"ip6\"; refactoring that changed the expected enum values.","solutions":["Pass exactly \"6\" or \"4\" (lowercase, no whitespace) as the v46 argument.","Normalize the value before calling: strings.TrimSpace(strings.ToLower(v)) and map aliases like \"ipv6\" to \"6\".","Validate the configured value at startup and fail with a clear config error instead of reaching this sentinel at dial time.","If the value is optional in your config, default it explicitly to \"4\" or \"6\" before invoking the plugin."],"exampleFix":"// before\nip, err := plugin.IP(cfg.Family) // cfg.Family == \"IPv6\"\n// after\nv46 := map[string]string{\"ipv6\": \"6\", \"ipv4\": \"4\", \"6\": \"6\", \"4\": \"4\"}[strings.ToLower(strings.TrimSpace(cfg.Family))]\nip, err := plugin.IP(v46)","handlingStrategy":"validation","validationCode":"func normalizeFamily(v string) (string, error) {\n    switch strings.ToLower(strings.TrimSpace(v)) {\n    case \"4\", \"ipv4\":\n        return \"4\", nil\n    case \"6\", \"ipv6\":\n        return \"6\", nil\n    default:\n        return \"\", fmt.Errorf(\"invalid family %q: must be 4 or 6\", v)\n    }\n}","typeGuard":"func isKnownFamily(v string) bool {\n    return v == \"4\" || v == \"6\"\n}","tryCatchPattern":"ip, err := plugin.IP(v46)\nif err != nil && err.Error() == \"black hole\" {\n    return fmt.Errorf(\"invalid family %q: must be exactly \\\"4\\\" or \\\"6\\\"\", v46)\n}","preventionTips":["Pass only the exact lowercase strings \"4\" or \"6\"; the check is case- and whitespace-sensitive.","Normalize config/env values (trim, lowercase, map aliases like ipv4/ipv6) before calling.","Validate family values at startup so bad config fails loudly before dial time.","Always set an explicit default for optional family settings instead of passing empty strings."],"tags":["go","network","invalid-argument","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"5cd13ef3b1fb574e88ebf2c1b5d95f2ebe1342c8","analyzedAt":"2026-09-06T04:35:00.432Z","contentChangedAt":"2026-09-06T04:35:00.432Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}