jeessy2/ddns-go · error
序列化请求体失败: %w
Error message
序列化请求体失败: %w
What it means
request() fails to json.Marshal the request body before sending it to the DNSMgr API. With the current callers the body is a map[string]interface{} of plain strings/ints, which is always marshalable in practice, so this error indicates a non-marshalable value reached request() (channels, funcs, invalid types) — typically after a code modification.
Source
Thrown at dns/hipmdnsmgr.go:196
// 参考 dnsmgr.ts 中的 request<T>() 方法
func (h *HiPMDnsMgr) request(baseURL, apiToken, method, path string, body interface{}) (*DnsMgrApiResponse, error) {
// 参考 dnsmgr.ts 中的 URL 处理方式
// Ensure baseUrl doesn't end with /api and path starts with /
base := strings.TrimSuffix(baseURL, "/")
base = strings.TrimSuffix(base, "/api")
normalizedPath := path
if !strings.HasPrefix(normalizedPath, "/") {
normalizedPath = "/" + normalizedPath
}
url := base + "/api" + normalizedPath
var bodyReader *bytes.Buffer
if body != nil {
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("序列化请求体失败: %w", err)
}
bodyReader = bytes.NewBuffer(jsonBody)
} else {
bodyReader = bytes.NewBuffer(nil)
}
req, err := http.NewRequest(method, url, bodyReader)
if err != nil {
return nil, err
}
// 设置请求头
headers := h.getHeaders(apiToken)
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := h.httpClient.Do(req)View on GitHub (pinned to 5874c2e666)
Solutions
- Inspect the wrapped %w cause — it names the unsupported json type
- Ensure every value in the request body map is a JSON-marshalable type (string, int, bool, slices, maps, tagged structs)
- Add json.Marshaler or proper struct tags for custom types
- If TTL came from config, confirm strconv.Atoi parsing didn't inject odd values (stock code defaults to 600 anyway)
Example fix
// before
body := map[string]interface{}{"callback": func(r *http.Request) {}} // unmarshalable
// after
body := map[string]interface{}{"name": name, "type": recordType, "value": value, "ttl": ttl, "line": "0"} Defensive patterns
Strategy: validation
Validate before calling
// guard before passing a body to any low-level request
func ensureMarshalable(body interface{}) error {
if body == nil {
return nil
}
_, err := json.Marshal(body)
return err // surfaces unmarshalable types before the HTTP call
} Prevention
- Only put JSON-native values (string, int, bool, slices, maps) in request bodies
- Avoid channels, funcs, or untagged custom structs in body maps
- Write a table test that marshals every request-body shape the provider builds
When it happens
Trigger: Calling createRecord/updateExistingRecord (via request) with a body containing a value that encoding/json cannot marshal: e.g. a channel, function, or cyclic/unsupported type placed into the body map.
Common situations: Developer adds a new field to the request body with a custom type lacking json marshaling, or passes a struct with unexported-only/unsupported fields; never occurs with stock string/int map bodies in normal operation.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to parse response data: %w
- failed to parse domain list: %w
- 异常信息: %s
- 监听端口发生异常, 请检查端口是否被占用! %s
- failed to decompress
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/abffefc1ab6a2b6d.
Report an issue: GitHub.