{"record":{"id":"32fca3f585506e46","repo":"GopeedLab/gopeed","slug":"invalid-request-url","errorCode":null,"errorMessage":"invalid request url","messagePattern":"invalid request url","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/base/model.go","lineNumber":48,"sourceCode":"\tr.Labels = labels\n}\n\n// PutLabel sets a label on the request.\nfunc (r *Request) PutLabel(key, value string) {\n\tif r.Labels == nil {\n\t\tr.Labels = make(map[string]string)\n\t}\n\tr.Labels[key] = value\n}\n\n// DelLabel deletes a label from the request.\nfunc (r *Request) DelLabel(key string) {\n\tdelete(r.Labels, key)\n}\n\nfunc (r *Request) Validate() error {\n\tif r.URL == \"\" {\n\t\treturn fmt.Errorf(\"invalid request url\")\n\t}\n\treturn nil\n}\n\ntype RequestProxyMode string\n\nconst (\n\t// RequestProxyModeFollow follow setting proxy\n\tRequestProxyModeFollow RequestProxyMode = \"follow\"\n\t// RequestProxyModeNone not use proxy\n\tRequestProxyModeNone RequestProxyMode = \"none\"\n\t// RequestProxyModeCustom custom proxy\n\tRequestProxyModeCustom RequestProxyMode = \"custom\"\n)\n\ntype RequestProxy struct {\n\tMode   RequestProxyMode `json:\"mode\"`\n\tScheme string           `json:\"scheme\"`","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/GopeedLab/gopeed/blob/7b7327ffb30816273a74b142cccc0bc10c5a4c67/pkg/base/model.go#L30-L66","documentation":"base.Request.Validate() (pkg/base/model.go:44) enforces the single invariant that a request must carry a URL. The URL is the key the whole fetch pipeline (resolve, proxying, fetcher selection) keys off, so an empty value is rejected up front rather than failing later inside a protocol adapter.","triggerScenarios":"Constructing base.Request{} and forgetting URL; deriving the URL from user input or config that trimmed to empty; copying a struct and clearing the field; JSON-decoding a payload where the url key was absent.","commonSituations":"CLI/web handlers that pass through empty form fields; config migrations renaming the field so deserialization leaves it zero; tests that build minimal requests and skip URL.","solutions":["Set a non-empty URL before calling Validate or submitting the request","Validate upstream input (trim + reject empty) so the error never reaches the library","When decoding from JSON, require the url key (disallow unknown/missing fields) to fail at the boundary"],"exampleFix":"// before\nreq := &base.Request{}\nerr := req.Validate() // \"invalid request url\"\n\n// after\nreq := &base.Request{URL: \"https://example.com/file.zip\"}\nerr := req.Validate()","handlingStrategy":"validation","validationCode":"func validRequestURL(raw string) bool {\n    u, err := url.Parse(strings.TrimSpace(raw))\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","typeGuard":null,"tryCatchPattern":"req := &base.Request{URL: strings.TrimSpace(input)}\nif err := req.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"invalid request url\") {\n        return fmt.Errorf(\"a non-empty request URL is required: %w\", err)\n    }\n    return err\n}","preventionTips":["Reject empty/whitespace URL input at the API boundary (CLI arg, form field, config)","When decoding JSON into base.Request, require the url key","Prefer base.Request.Validate() as the first step of any submission path"],"tags":["validation","model","request","input"],"backgroundTag":null,"analyzedSha":"7b7327ffb30816273a74b142cccc0bc10c5a4c67","analyzedAt":"2026-08-16T02:51:03.250Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}