jeessy2/ddns-go · error
failed to parse domain list: %w
Error message
failed to parse domain list: %w
What it means
When the keyword-query response data is a JSON array, getDomainID re-marshals it and unmarshals into []DnsMgrDomain; if the array elements don't match the DnsMgrDomain field types (id/account_id/record_count expected numbers; name/third_id strings), this wrapped error is returned.
Source
Thrown at dns/hipmdnsmgr.go:255
}
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:
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, nilView on GitHub (pinned to 5874c2e666)
Solutions
- Curl the endpoint and check the array element types against DnsMgrDomain (numeric id, string name)
- If the server returns string IDs, change DnsMgrDomain.ID to json.Number or string and convert
- Align the DNSMgr server version with the schema this client expects
- Check the wrapped %w message — it names the exact field and Go type mismatch
Example fix
// before (server response)
[{"id":"12","name":"example.com"}]
// after (client fix)
type DnsMgrDomain struct {
ID json.Number `json:"id"`
Name string `json:"name"`
...
} Defensive patterns
Strategy: type-guard
Type guard
func isDomainArray(data json.RawMessage) ([]DnsMgrDomain, error) {
var arr []map[string]interface{}
if err := json.Unmarshal(data, &arr); err != nil {
return nil, err
}
for _, m := range arr {
if _, ok := m["id"].(float64); !ok {
return nil, fmt.Errorf("domain id is not numeric")
}
if _, ok := m["name"].(string); !ok {
return nil, fmt.Errorf("domain name is not a string")
}
}
var domains []DnsMgrDomain
b, _ := json.Marshal(arr)
return domains, json.Unmarshal(b, &domains)
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to parse domain list") {
log.Printf("domain schema mismatch; inspect /api/domains item types: %v", err)
// fall back to manual field mapping via map[string]interface{}
} Prevention
- Keep DNSMgr server and ddns-go client versions schema-compatible
- Use json.Number or string+convert for ID fields to tolerate string-typed IDs
- Add a unit test unmarshaling a captured real API response into DnsMgrDomain
When it happens
Trigger: The /domains keyword search returns a top-level JSON array whose items have mismatched types, e.g. id as string "12" instead of number, causing json.Unmarshal into []DnsMgrDomain to fail.
Common situations: DNSMgr server version emitting string-typed IDs; a different compatible API (alternate backend) with a slightly different domain schema; custom server forks returning extra/renamed fields with wrong types.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse response data: %w
- invalid response format: missing list field
- unknown response data format: %T
- failed to parse record list: %w
- 序列化请求体失败: %w
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/38622bf2923f2cea.
Report an issue: GitHub.