slackhq/nebula · error
config `%s` has invalid type: %T
Error message
config `%s` has invalid type: %T
What it means
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.
Source
Thrown at calculated_remote.go:89
maskb = binary.BigEndian.Uint64(mask[8:])
maskAddrb = binary.BigEndian.Uint64(maskAddr[8:])
calcAddrb = binary.BigEndian.Uint64(calcAddr[8:])
ap.Lo = (maskAddrb & maskb) | (calcAddrb & ^maskb)
return &ap
}
func NewCalculatedRemotesFromConfig(c *config.C, k string) (*bart.Table[[]*calculatedRemote], error) {
value := c.Get(k)
if value == nil {
return nil, nil
}
calculatedRemotes := new(bart.Table[[]*calculatedRemote])
rawMap, ok := value.(map[string]any)
if !ok {
return nil, fmt.Errorf("config `%s` has invalid type: %T", k, value)
}
for rawCIDR, rawValue := range rawMap {
cidr, err := netip.ParsePrefix(rawCIDR)
if err != nil {
return nil, fmt.Errorf("config `%s` has invalid CIDR: %s", k, rawCIDR)
}
entry, err := newCalculatedRemotesListFromConfig(cidr, rawValue)
if err != nil {
return nil, fmt.Errorf("config '%s.%s': %w", k, rawCIDR, err)
}
calculatedRemotes.Insert(cidr, entry)
}
return calculatedRemotes, nil
}
View on GitHub (pinned to dd8f660c0a)
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
Example fix
// before
lighthouse:
calculated_remotes: 10.0.42.0/24
// after
lighthouse:
calculated_remotes:
10.0.42.0/24:
- mask: 10.0.0.0/8
port: 4242 Defensive patterns
Strategy: validation
Validate before calling
value := c.Get("lighthouse")
if value != nil {
if _, ok := value.(map[string]any); !ok {
return fmt.Errorf("lighthouse.calculated_remotes must be a table, got %T", value)
}
} Type guard
func isConfigTable(v any) bool {
_, ok := v.(map[string]any)
return ok
} Try / catch
tbl, err := NewCalculatedRemotesFromConfig(c, "lighthouse.calculated_remotes")
if err != nil {
if strings.Contains(err.Error(), "has invalid type") {
return fmt.Errorf("check calculated_remotes structure in config: %w", err)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- calculated_remotes entry has invalid type: %T
- invalid type: %T
- invalid mask (type %T): %v
- config `%s` has invalid type: %T
- invalid mask: %s for cidr: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/5a0c85b9968529fb.
Report an issue: GitHub.