flipped-aurora/gin-vue-admin · error

httpUrl 必须是合法的 http/https 地址

Error message

httpUrl 必须是合法的 http/https 地址

What it means

validateTask throws "httpUrl 必须是合法的 http/https 地址" for HTTP-executor tasks when url.Parse fails, the scheme is not http/https, or the host is empty. This ensures the scheduler only dispatches to well-formed web endpoints.

Source

Thrown at server/service/system/sys_timed_task.go:63

func (s *TimedTaskService) validateTask(t *system.SysTimedTask) error {
	if t.Name == "" {
		return errors.New("任务名不能为空")
	}
	if err := s.ValidateSpec(t.Spec, t.WithSeconds); err != nil {
		return err
	}
	switch t.ExecutorType {
	case system.TimedTaskExecutorMethod:
		if _, ok := task.Get(t.MethodName); !ok {
			return fmt.Errorf("方法 %s 未注册", t.MethodName)
		}
		if len(t.Params) > 0 && !json.Valid(t.Params) {
			return errors.New("params 必须是合法 JSON")
		}
	case system.TimedTaskExecutorHTTP:
		u, err := url.Parse(t.HttpUrl)
		if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
			return errors.New("httpUrl 必须是合法的 http/https 地址")
		}
		if len(t.HttpHeader) > 0 {
			var hdr map[string]string
			if err := json.Unmarshal(t.HttpHeader, &hdr); err != nil {
				return errors.New(`httpHeader 必须是 {"Key":"Value"} 形式的 JSON 对象`)
			}
		}
	default:
		return fmt.Errorf("executorType 必须为 %s 或 %s", system.TimedTaskExecutorMethod, system.TimedTaskExecutorHTTP)
	}
	return nil
}

// checkNameUnique 软删除下不建 DB 唯一索引, 由服务层保证活跃行内唯一
func (s *TimedTaskService) checkNameUnique(ctx context.Context, name string, excludeID uint) error {
	var count int64
	db := global.GVA_DB.WithContext(ctx).Model(&system.SysTimedTask{}).Where("name = ?", name)
	if excludeID > 0 {

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Include an explicit http:// or https:// scheme and a host in HttpUrl.
  2. Trim whitespace from the URL before submitting.
  3. Pre-validate with url.Parse in the client and check u.Scheme and u.Host.
  4. Confirm the correct executor type: if you meant a registered method, use TimedTaskExecutorMethod instead.

Example fix

// before
HttpUrl: "api.internal.local/ping"

// after
HttpUrl: "http://api.internal.local/ping"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(strings.TrimSpace(task.HttpUrl))
if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" {
    return errors.New("httpUrl must be an absolute http/https URL")
}

Type guard

func validHTTPUrl(s string) bool {
    u, err := url.Parse(strings.TrimSpace(s))
    return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != ""
}

Try / catch

if err := svc.CreateTimedTask(ctx, task); err != nil {
    if strings.Contains(err.Error(), "httpUrl 必须是合法") {
        http.Error(w, "provide an absolute http(s) URL with host", http.StatusBadRequest)
        return
    }
    http.Error(w, err.Error(), http.StatusInternalServerError)
}

Prevention

When it happens

Trigger: Creating/updating a task with ExecutorType=TimedTaskExecutorHTTP and HttpUrl like "example.com/api" (no scheme), "ftp://host", "http://" (empty host), or a string with spaces/illegal characters that makes url.Parse error.

Common situations: Users omitting the http:// prefix; internal URLs with typos; URLs pasted with surrounding whitespace; environment config where a base URL variable is empty so the URL becomes "/path" only.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/88856f9f24d39094. Report an issue: GitHub.