jeessy2/ddns-go · error

failed to parse response data: %w

Error message

failed to parse response data: %w

What it means

getDomainID could not json.Unmarshal the API response's 'data' field into a generic interface{} before format detection. This means the data field is not valid JSON (e.g. null literal handled oddly, truncated body, or a non-JSON payload string).

Source

Thrown at dns/hipmdnsmgr.go:248

func (h *HiPMDnsMgr) getDomainID(baseURL, apiToken, domainName string) (int, error) {
	// Method 1: Use keyword parameter for direct query (efficient)
	path := fmt.Sprintf("/domains?page=1&pageSize=1&keyword=%s", domainName)

	apiResp, err := h.request(baseURL, apiToken, "GET", path, nil)
	if err != nil {
		return 0, err
	}

	if apiResp.Code != 0 {
		return 0, fmt.Errorf("API error: %s", apiResp.Msg)
	}

	var domains []DnsMgrDomain

	// Smart detection: support both array and object formats
	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:

View on GitHub (pinned to 5874c2e666)

Solutions

  1. Curl the same endpoint and inspect the raw 'data' value for validity
  2. Check for proxies/middleware altering response bodies
  3. Upgrade or fix the DNSMgr server so /domains returns well-formed JSON data
  4. Capture the wrapped %w message for the precise json error (offset/syntax) to pinpoint the malformation

Example fix

// before: response
{"code":0,"data":"<html>error page</html>","msg":""}
// after: expected
{"code":0,"data":{"list":[{"id":1,"name":"example.com"}]},"msg":""}
Defensive patterns

Strategy: type-guard

Type guard

func isValidJSON(b []byte) bool {
    var v interface{}
    return json.Unmarshal(b, &v) == nil
}
// guard the data field before parsing
if !isValidJSON(apiResp.Data) {
    return fmt.Errorf("malformed data field from API")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to parse response data") {
    log.Printf("DNSMgr returned non-JSON data payload; check proxies/server health: %v", err)
    return // don't retry immediately; investigate server/proxy
}

Prevention

When it happens

Trigger: The DNSMgr /domains keyword query returns HTTP 200 with a code==0 envelope whose 'data' contains invalid or unexpected JSON that cannot unmarshal into interface{}.

Common situations: A proxy or self-hosted reverse proxy truncating/rewriting the response; DNSMgr version emitting a data payload type the parser doesn't expect; corrupted response body from a flaky network layer decoded by the shared http.Client.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — 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/56f2f8daf8768eab. Report an issue: GitHub.