{"record":{"id":"9f7f46b1889d902d","repo":"flipped-aurora/gin-vue-admin","slug":"httpheader-key-value-json","errorCode":null,"errorMessage":"httpHeader 必须是 {\"Key\":\"Value\"} 形式的 JSON 对象","messagePattern":"httpHeader 必须是 (.+?) 形式的 JSON 对象","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_timed_task.go","lineNumber":68,"sourceCode":"\t\treturn err\n\t}\n\tswitch t.ExecutorType {\n\tcase system.TimedTaskExecutorMethod:\n\t\tif _, ok := task.Get(t.MethodName); !ok {\n\t\t\treturn fmt.Errorf(\"方法 %s 未注册\", t.MethodName)\n\t\t}\n\t\tif len(t.Params) > 0 && !json.Valid(t.Params) {\n\t\t\treturn errors.New(\"params 必须是合法 JSON\")\n\t\t}\n\tcase system.TimedTaskExecutorHTTP:\n\t\tu, err := url.Parse(t.HttpUrl)\n\t\tif err != nil || (u.Scheme != \"http\" && u.Scheme != \"https\") || u.Host == \"\" {\n\t\t\treturn errors.New(\"httpUrl 必须是合法的 http/https 地址\")\n\t\t}\n\t\tif len(t.HttpHeader) > 0 {\n\t\t\tvar hdr map[string]string\n\t\t\tif err := json.Unmarshal(t.HttpHeader, &hdr); err != nil {\n\t\t\t\treturn errors.New(`httpHeader 必须是 {\"Key\":\"Value\"} 形式的 JSON 对象`)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"executorType 必须为 %s 或 %s\", system.TimedTaskExecutorMethod, system.TimedTaskExecutorHTTP)\n\t}\n\treturn nil\n}\n\n// checkNameUnique 软删除下不建 DB 唯一索引, 由服务层保证活跃行内唯一\nfunc (s *TimedTaskService) checkNameUnique(ctx context.Context, name string, excludeID uint) error {\n\tvar count int64\n\tdb := global.GVA_DB.WithContext(ctx).Model(&system.SysTimedTask{}).Where(\"name = ?\", name)\n\tif excludeID > 0 {\n\t\tdb = db.Where(\"id <> ?\", excludeID)\n\t}\n\tif err := db.Count(&count).Error; err != nil {\n\t\treturn err\n\t}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_timed_task.go#L50-L86","documentation":"validateTask throws \"httpHeader 必须是 {\\\"Key\\\":\\\"Value\\\"} 形式的 JSON 对象\" when a non-empty HttpHeader byte slice cannot be unmarshalled into map[string]string. Headers must be a flat JSON object of string keys to string values.","triggerScenarios":"Setting HttpHeader to a JSON array, a nested object ({\"a\":{\"b\":1}}), non-string values ({\"count\":1}), or invalid JSON; client sending headers as an array of {key,value} pairs.","commonSituations":"Copying curl -H style headers verbatim; frontends representing headers as arrays; numeric or boolean header values that Go's map[string]string cannot unmarshal.","solutions":["Send HttpHeader as a flat JSON object with string values, e.g. {\"Authorization\":\"Bearer x\"}.","Convert array-style header lists to an object before calling the API.","Coerce numeric/boolean header values to strings client-side.","Omit HttpHeader entirely when no custom headers are needed."],"exampleFix":"// before\nHttpHeader: []byte(`[{\"key\":\"Authorization\",\"value\":\"Bearer x\"}]`)\n\n// after\nHttpHeader: []byte(`{\"Authorization\":\"Bearer x\"}`)","handlingStrategy":"validation","validationCode":"if len(task.HttpHeader) > 0 {\n    var hdr map[string]string\n    if err := json.Unmarshal(task.HttpHeader, &hdr); err != nil {\n        return errors.New(\"httpHeader must be a flat JSON object of string->string\")\n    }\n}","typeGuard":"func validHTTPHeader(p []byte) bool {\n    var hdr map[string]string\n    return len(p) == 0 || json.Unmarshal(p, &hdr) == nil\n}","tryCatchPattern":"if err := svc.UpdateTimedTask(ctx, task); err != nil {\n    if strings.Contains(err.Error(), \"httpHeader 必须\") {\n        http.Error(w, `httpHeader must be {\"Key\":\"Value\"} JSON`, http.StatusBadRequest)\n        return\n    }\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n}","preventionTips":["Represent headers as key/value maps, not arrays","Coerce header values to strings before serializing","Omit the field entirely when unused","Validate with json.Unmarshal into map[string]string in tests"],"tags":["validation","json","http-headers","go"],"backgroundTag":"json-schema-mismatch","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}