{"record":{"id":"5a0c85b9968529fb","repo":"slackhq/nebula","slug":"config-s-has-invalid-type-t-5a0c85","errorCode":null,"errorMessage":"config `%s` has invalid type: %T","messagePattern":"config `(.+?)` has invalid type: %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"calculated_remote.go","lineNumber":89,"sourceCode":"\tmaskb = binary.BigEndian.Uint64(mask[8:])\n\tmaskAddrb = binary.BigEndian.Uint64(maskAddr[8:])\n\tcalcAddrb = binary.BigEndian.Uint64(calcAddr[8:])\n\tap.Lo = (maskAddrb & maskb) | (calcAddrb & ^maskb)\n\n\treturn &ap\n}\n\nfunc NewCalculatedRemotesFromConfig(c *config.C, k string) (*bart.Table[[]*calculatedRemote], error) {\n\tvalue := c.Get(k)\n\tif value == nil {\n\t\treturn nil, nil\n\t}\n\n\tcalculatedRemotes := new(bart.Table[[]*calculatedRemote])\n\n\trawMap, ok := value.(map[string]any)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"config `%s` has invalid type: %T\", k, value)\n\t}\n\tfor rawCIDR, rawValue := range rawMap {\n\t\tcidr, err := netip.ParsePrefix(rawCIDR)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"config `%s` has invalid CIDR: %s\", k, rawCIDR)\n\t\t}\n\n\t\tentry, err := newCalculatedRemotesListFromConfig(cidr, rawValue)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"config '%s.%s': %w\", k, rawCIDR, err)\n\t\t}\n\n\t\tcalculatedRemotes.Insert(cidr, entry)\n\t}\n\n\treturn calculatedRemotes, nil\n}\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/calculated_remote.go#L71-L107","documentation":"NewCalculatedRemotesFromConfig reads the `lighthouse.calculated_remotes` key and asserts the raw value is a map[string]any (a TOML/YAML table keyed by CIDR). If the configured value is any other type (string, list, bool, number), the library cannot enumerate CIDR keys and throws this error including the offending Go type.","triggerScenarios":"Calling NewCalculatedRemotesFromConfig (via reload) when the configured `calculated_remotes` value is not a table/map — e.g. a bare string, an array, or a scalar in the nebula config file.","commonSituations":"YAML/TOML indentation mistakes that collapse the calculated_remotes block into a scalar, or users writing calculated_remotes as a list instead of a map of CIDRs.","solutions":["Rewrite the calculated_remotes value as a mapping from CIDR strings to entry lists","Check the %T in the error message to see what type was actually parsed (e.g. string vs map)","Fix file indentation so nested entries parse as a table, not a continuation of the parent key"],"exampleFix":"// before\nlighthouse:\n  calculated_remotes: 10.0.42.0/24\n// after\nlighthouse:\n  calculated_remotes:\n    10.0.42.0/24:\n      - mask: 10.0.0.0/8\n        port: 4242","handlingStrategy":"validation","validationCode":"value := c.Get(\"lighthouse\")\nif value != nil {\n\tif _, ok := value.(map[string]any); !ok {\n\t\treturn fmt.Errorf(\"lighthouse.calculated_remotes must be a table, got %T\", value)\n\t}\n}","typeGuard":"func isConfigTable(v any) bool {\n\t_, ok := v.(map[string]any)\n\treturn ok\n}","tryCatchPattern":"tbl, err := NewCalculatedRemotesFromConfig(c, \"lighthouse.calculated_remotes\")\nif err != nil {\n\tif strings.Contains(err.Error(), \"has invalid type\") {\n\t\treturn fmt.Errorf(\"check calculated_remotes structure in config: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Verify YAML indentation so nested keys parse as a map, not a scalar","Assert the section is a mapping before handing it to NewCalculatedRemotesFromConfig","Use a YAML/TOML schema validator on the nebula config at startup"],"tags":["nebula","config","type-error","yaml","calculated-remotes"],"backgroundTag":"config-type-mismatch","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}