jeessy2/ddns-go · error

invalid response format: missing list field

Error message

invalid response format: missing list field

What it means

When the keyword-query response data is a JSON object, getDomainID expects a 'list' key holding the domain array. If the object has no 'list' field, this error signals the response envelope doesn't match the expected PageResult shape — i.e. the server returned an unrecognized object format.

Source

Thrown at dns/hipmdnsmgr.go:264

	var rawData interface{}
	if err := json.Unmarshal(apiResp.Data, &rawData); err != nil {
		return 0, fmt.Errorf("failed to parse response data: %w", err)
	}

	switch v := rawData.(type) {
	case []interface{}:
		jsonData, _ := json.Marshal(v)
		if err := json.Unmarshal(jsonData, &domains); err != nil {
			return 0, fmt.Errorf("failed to parse domain list: %w", err)
		}
	case map[string]interface{}:
		if listData, ok := v["list"]; ok {
			jsonData, _ := json.Marshal(listData)
			if err := json.Unmarshal(jsonData, &domains); err != nil {
				return 0, fmt.Errorf("failed to parse domain list: %w", err)
			}
		} else {
			return 0, fmt.Errorf("invalid response format: missing list field")
		}
	default:
		return 0, fmt.Errorf("unknown response data format: %T", rawData)
	}

	// Check if exact match is found
	for _, d := range domains {
		if d.Name == domainName {
			return d.ID, nil
		}
	}

	// Method 2: If keyword query not found, use list matching as fallback (compatible with old API)
	// Paginate through all domains to find the target
	const pageSize = 100
	currentPage := 1

	for {

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Curl the endpoint and inspect the actual data object keys
  2. Add support for the new shape in getDomainID's switch (e.g. accept v["domains"] or a direct object)
  3. Downgrade/align the DNSMgr server with the API contract this client expects
  4. Check whether the keyword query path /domains?page=1&pageSize=1&keyword=... is still valid in your server version

Example fix

// before (server)
{"code":0,"data":{"domains":[...],"total":1}}
// after (client)
case map[string]interface{}:
    listKey := "list"
    if _, ok := v["list"]; !ok {
        listKey = "domains" // fallback for newer API
    }
    if listData, ok := v[listKey]; ok { ... }
Defensive patterns

Strategy: validation

Validate before calling

// verify the API still returns the expected PageResult envelope
var probe struct {
    Code int             `json:"code"`
    Data json.RawMessage `json:"data"`
}
// GET /api/domains?page=1&pageSize=1 then:
var obj map[string]json.RawMessage
if err := json.Unmarshal(probe.Data, &obj); err != nil {
    return fmt.Errorf("data is not an object")
}
if _, ok := obj["list"]; !ok {
    return fmt.Errorf("API no longer returns 'list' field; client upgrade needed")
}

Type guard

func hasListField(data json.RawMessage) bool {
    var obj map[string]json.RawMessage
    return json.Unmarshal(data, &obj) == nil && obj["list"] != nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "missing list field") {
    log.Printf("DNSMgr response envelope changed; pin server version or upgrade ddns-go: %v", err)
}

Prevention

When it happens

Trigger: GET /domains?page=1&pageSize=1&keyword=<domain> returns data as an object without a 'list' key (e.g. data is the domain object directly, or {domains:[...]}, or an error object inside a code==0 envelope).

Common situations: DNSMgr API version change renaming or nesting the list field; a server that returns the matched domain object directly for keyword searches; misrouted request hitting a different endpoint that returns an object-shaped payload.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03). Data as JSON: /api/errors/9e6e16a2bf8d9e14. Report an issue: GitHub.