{"record":{"id":"e2ec87325a569dd3","repo":"Wei-Shaw/sub2api","slug":"proxy-protocol-is-required","errorCode":null,"errorMessage":"proxy protocol is required","messagePattern":"proxy protocol is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/internal/handler/admin/account_data.go","lineNumber":656,"sourceCode":"func validateDataHeader(payload DataPayload) error {\n\tif payload.Type != \"\" && payload.Type != dataType && payload.Type != legacyDataType {\n\t\treturn fmt.Errorf(\"unsupported data type: %s\", payload.Type)\n\t}\n\tif payload.Version != 0 && payload.Version != dataVersion {\n\t\treturn fmt.Errorf(\"unsupported data version: %d\", payload.Version)\n\t}\n\tif payload.Proxies == nil {\n\t\treturn errors.New(\"proxies is required\")\n\t}\n\tif payload.Accounts == nil {\n\t\treturn errors.New(\"accounts is required\")\n\t}\n\treturn nil\n}\n\nfunc validateDataProxy(item DataProxy) error {\n\tif strings.TrimSpace(item.Protocol) == \"\" {\n\t\treturn errors.New(\"proxy protocol is required\")\n\t}\n\tif strings.TrimSpace(item.Host) == \"\" {\n\t\treturn errors.New(\"proxy host is required\")\n\t}\n\tif item.Port <= 0 || item.Port > 65535 {\n\t\treturn errors.New(\"proxy port is invalid\")\n\t}\n\tswitch item.Protocol {\n\tcase \"http\", \"https\", \"socks5\", \"socks5h\":\n\tdefault:\n\t\treturn fmt.Errorf(\"proxy protocol is invalid: %s\", item.Protocol)\n\t}\n\tif item.Status != \"\" {\n\t\tnormalizedStatus := normalizeProxyStatus(item.Status)\n\t\tif normalizedStatus != service.StatusActive && normalizedStatus != \"inactive\" {\n\t\t\treturn fmt.Errorf(\"proxy status is invalid: %s\", item.Status)\n\t\t}\n\t}","sourceCodeStart":638,"sourceCodeEnd":674,"githubUrl":"https://github.com/Wei-Shaw/sub2api/blob/073e92d17178a1ccdb0a27017f572f10c9c7ab62/backend/internal/handler/admin/account_data.go#L638-L674","documentation":"Returned by validateDataProxy (backend/internal/handler/admin/account_data.go:656) for a proxy entry whose protocol is empty after TrimSpace. Protocol is the first per-proxy field checked; it must then be one of http, https, socks5, socks5h (a different error, 'proxy protocol is invalid', covers unknown values).","triggerScenarios":"A proxies[] entry with protocol missing, empty string, or only whitespace; schema renamed (scheme vs protocol) so the field is never populated.","commonSituations":"Exporting from a tool that calls it 'scheme'; hand-written proxy entries; trailing-whitespace protocol from a form input.","solutions":["Set protocol to one of http, https, socks5, socks5h on every proxies[] entry.","If your source data uses 'scheme', map it to 'protocol' when building the payload.","Trim inputs client-side before submit."],"exampleFix":"// before\n{ \"host\": \"127.0.0.1\", \"port\": 7890 }\n\n// after\n{ \"protocol\": \"socks5\", \"host\": \"127.0.0.1\", \"port\": 7890 }","handlingStrategy":"validation","validationCode":"const PROXY_PROTOCOLS = new Set(['http', 'https', 'socks5', 'socks5h'])\nfunction hasProxyProtocol(entry: Record<string, unknown>): boolean {\n  return typeof entry.protocol === 'string' && PROXY_PROTOCOLS.has(entry.protocol.trim())\n}","typeGuard":"function isPlausibleDataProxy(e: unknown): e is { protocol: string; host: string; port: number } {\n  if (typeof e !== 'object' || e === null) return false\n  const o = e as Record<string, unknown>\n  return typeof o.protocol === 'string' && o.protocol.trim() !== '' &&\n    typeof o.host === 'string' && o.host.trim() !== '' &&\n    typeof o.port === 'number' && Number.isInteger(o.port) && o.port >= 1 && o.port <= 65535\n}","tryCatchPattern":null,"preventionTips":["Normalize your source's 'scheme' field to 'protocol' when building payloads.","Offer a fixed dropdown (http/https/socks5/socks5h) instead of free text.","Trim whitespace on all string fields before submit."],"tags":["admin","import","proxy","validation","backend"],"backgroundTag":null,"analyzedSha":"073e92d17178a1ccdb0a27017f572f10c9c7ab62","analyzedAt":"2026-08-15T14:33:00.750Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}