{"record":{"id":"741ce7e8672bba08","repo":"flipped-aurora/gin-vue-admin","slug":"s-741ce7","errorCode":null,"errorMessage":"方法 %s 未注册","messagePattern":"方法 (.+?) 未注册","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/sys_timed_task.go","lineNumber":55,"sourceCode":"\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cron 表达式非法: %w\", err)\n\t}\n\treturn nil\n}\n\n// validateTask 落库前统一校验(创建/更新共用)\nfunc (s *TimedTaskService) validateTask(t *system.SysTimedTask) error {\n\tif t.Name == \"\" {\n\t\treturn errors.New(\"任务名不能为空\")\n\t}\n\tif err := s.ValidateSpec(t.Spec, t.WithSeconds); err != nil {\n\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}","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/sys_timed_task.go#L37-L73","documentation":"validateTask verifies that a method-executor timed task references a registered method. task.Get(t.MethodName) looks the name up in the task registry; if absent, creation/update is rejected with '方法 %s 未注册'. This guards against persisting tasks that could never be dispatched at runtime.","triggerScenarios":"Creating or updating a timed task with ExecutorType=TimedTaskExecutorMethod where MethodName does not match any method registered in the task registry (typo, method never registered, or plugin providing the method not loaded).","commonSituations":"Typo in MethodName vs. the name passed to task.Add during registration; service restarted without the plugin that registers the method; method removed/renamed in code while old task definitions still reference it; copying a task config between environments with different registered methods.","solutions":["Check the exact registered name at the task.Add call site and fix MethodName to match","Verify the code/plugin that registers the method is actually loaded at startup","List available registered methods (or add debug logging around task.Get) to discover valid names","If the method was removed or renamed, update the task to a currently registered method"],"exampleFix":"// before\n{ \"executorType\": \"method\", \"methodName\": \"ClearCacheJob\" } // never registered\n// after\n// in registration code:\ntask.Add(\"system.ClearCache\", func(...) error { ... })\n// in task:\n{ \"executorType\": \"method\", \"methodName\": \"system.ClearCache\" }","handlingStrategy":"validation","validationCode":"// Go: check registry membership before creating a method task\nif _, ok := task.Get(methodName); !ok {\n    return fmt.Errorf(\"方法 %s 未注册\", methodName)\n}","typeGuard":"// Go: registered-method guard\nfunc methodRegistered(name string) bool {\n    _, ok := task.Get(name)\n    return ok\n}","tryCatchPattern":"err := svc.CreateTimedTask(t)\nif err != nil && strings.Contains(err.Error(), \"未注册\") {\n    // inspect registry / task.Add call sites, fix MethodName, resubmit\n    return fmt.Errorf(\"请使用已注册的方法名: %w\", err)\n}","preventionTips":["Copy MethodName from the exact string passed to task.Add — avoid retyping","Ensure the plugin/service registering the method is loaded before task creation","When renaming a method, migrate existing task rows referencing the old name","Maintain a single source of truth (constants) for registered method names"],"tags":["task-registry","validation","go"],"backgroundTag":"method-not-registered","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}