{"record":{"id":"e00ef312ad47f267","repo":"siyuan-note/siyuan","slug":"parse-t-failed-s","errorCode":null,"errorMessage":"parse [t] failed: %s","messagePattern":"parse \\[t\\] failed: (.+?)","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"kernel/api/network.go","lineNumber":391,"sourceCode":"\t\t}\n\t\tvar record map[string][]string\n\t\tif jsonErr := json.Unmarshal(hBytes, &record); jsonErr != nil {\n\t\t\terr = fmt.Errorf(\"parse [h] failed: %s\", jsonErr.Error())\n\t\t\treturn\n\t\t}\n\n\t\tfor k, vs := range record {\n\t\t\tfor _, v := range vs {\n\t\t\t\th.Add(k, v)\n\t\t\t}\n\t\t}\n\t}\n\n\ttimeout = 30 * time.Second\n\ttParam := c.Query(\"t\")\n\tif tParam != \"\" {\n\t\tif t, parseErr := time.ParseDuration(tParam); parseErr != nil {\n\t\t\terr = fmt.Errorf(\"parse [t] failed: %s\", parseErr.Error())\n\t\t\treturn\n\t\t} else {\n\t\t\ttimeout = t\n\t\t}\n\t}\n\n\treturn\n}\n\n// forwardResponseHeaders copies src headers into dst with a \"Siyuan-Proxy-\" prefix on each key.\nfunc forwardResponseHeaders(dst http.Header, src http.Header) {\n\tfor k, vs := range src {\n\t\tfor _, v := range vs {\n\t\t\tdst.Add(\"Siyuan-Proxy-\"+k, v)\n\t\t}\n\t}\n}\n","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/api/network.go#L373-L409","documentation":"Returned by parseForwardProxyParams (network.go:391) when the optional `t` (timeout) query parameter is present but cannot be parsed by time.ParseDuration. The value must be a Go duration string (e.g. '30s', '2m', '1500ms', '1h30m'); an unparseable value yields this error and the request is rejected with HTTP 400 before the proxy client dials.","triggerScenarios":"Sending ?t=30000 (a bare integer, not a duration), ?t=30 (intended seconds but missing unit), ?t=30sec (wrong unit suffix), or ?t=NaN. time.ParseDuration at network.go:390 fails and the error is wrapped at line 391. Note the default when `t` is omitted is 30s (line 387).","commonSituations":"Caller passes milliseconds as a plain number assuming seconds. Caller uses JS-style '30s' correctly but accidentally sends '30' from a numeric input. Locale/formatting inserted a decimal separator or unit typo. The docstring says 'nanoseconds' but the parser expects Go duration syntax.","solutions":["Send `t` as a Go duration string with an explicit unit: '30s', '2m', '500ms'.","If you only have a number of seconds, append 's': String(seconds) + 's'.","If you do not need a custom timeout, omit `t` to use the 30s default."],"exampleFix":"// before\nfetch(`/api/network/forwardProxy?u=${u}&t=30`)\n// after\nfetch(`/api/network/forwardProxy?u=${u}&t=30s`)","handlingStrategy":"validation","validationCode":"// Convert a seconds number to a Go duration string, or omit for default\nconst t = seconds ? `${seconds}s` : undefined;\nconst q = new URLSearchParams({ u }); if (t) q.set('t', t);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a time unit ('s','ms','m') in `t`.","Omit `t` to use the 30s default rather than guessing.","Add a test asserting time.ParseDuration accepts your emitted value."],"tags":["network","proxy","validation","kernel"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}