lionsoul2014/ip2region · error

invalid ip value type %s

Error message

invalid ip value type %s

What it means

Search only accepts string or []byte ip values. Any other Go type (int, net.IP, netip.Addr, nil, etc.) hits the default branch and returns this error. net.IP is []byte under the hood but a distinct named type, so it also falls through unless converted.

Source

Thrown at binding/golang/xdb/searcher.go:123

// GetIOCount return the global io count for the last search
func (s *Searcher) GetIOCount() int {
	return s.ioCount
}

// Search the region for the specified string or bytes ip address
func (s *Searcher) Search(ip any) (string, error) {
	var err error
	var ipBytes []byte
	switch v := ip.(type) {
	case string:
		ipBytes, err = ParseIP(v)
		if err != nil {
			return "", fmt.Errorf("parse ip %s: %w", v, err)
		}
	case []byte:
		ipBytes = v
	default:
		return "", fmt.Errorf("invalid ip value type %s", v)
	}

	// ip version check
	if len(ipBytes) != s.version.Bytes {
		return "", fmt.Errorf("invalid ip address(%s expected)", s.version.Name)
	}

	// reset the global ioCount
	s.ioCount = 0

	// locate the segment index block based on the vector index
	var il0, il1 = int(ipBytes[0]), int(ipBytes[1])
	var idx = il0*VectorIndexCols*VectorIndexSize + il1*VectorIndexSize
	var sPtr, ePtr = uint32(0), uint32(0)
	if s.vectorIndex != nil {
		sPtr = binary.LittleEndian.Uint32(s.vectorIndex[idx:])
		ePtr = binary.LittleEndian.Uint32(s.vectorIndex[idx+4:])
	} else if s.contentBuff != nil {

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Convert net.IP to []byte: []byte(netIP) or netIP.To4()/To16().
  2. Use addr.AsSlice() for netip.Addr, or a string via addr.String().
  3. Format integers as dotted string only if you really mean an IPv4 int; otherwise convert to 4-byte slice.
  4. Switch to searchByBytes-style flow with an explicitly validated []byte.

Example fix

// before
region, err := searcher.Search(ctx, netIP) // net.IP type → error
// after
region, err := searcher.Search(ctx, []byte(netIP.To16()))
Defensive patterns

Strategy: type-guard

Validate before calling

switch v := ipArg.(type) {
case string:
    if net.ParseIP(v) == nil { return errors.New("bad ip string") }
case []byte:
    if len(v) != 4 && len(v) != 16 { return errors.New("bad ip bytes") }
default:
    return fmt.Errorf("unsupported ip type %T", ipArg)
}

Type guard

func isSearchableIP(v interface{}) bool {
    switch t := v.(type) {
    case string:
        return net.ParseIP(t) != nil
    case []byte:
        return len(t) == 4 || len(t) == 16
    default:
        return false
    }
}

Try / catch

region, err := searcher.Search(ctx, ipArg)
if err != nil && strings.Contains(err.Error(), "invalid ip value type") {
    return fmt.Errorf("convert ip to string or []byte first (type %T)", ipArg)
}

Prevention

When it happens

Trigger: Passing a net.IP value directly to Search; passing an int or uint32; passing nil interface; passing netip.Addr.

Common situations: Developers assume net.IP works because it is byte-backed; parsing with netip and forwarding the Addr instead of its As4()/As16() slice.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02). Data as JSON: /api/errors/ae3651eeb4d36254. Report an issue: GitHub.