{"record":{"id":"d6f9b9f763e5bc77","repo":"caddyserver/caddy","slug":"humanize-size-cannot-be-parsed-s","errorCode":null,"errorMessage":"humanize: size cannot be parsed: %s","messagePattern":"humanize: size cannot be parsed: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"modules/caddyhttp/templates/tplcontext.go","lineNumber":484,"sourceCode":"\n// funcHumanize transforms size and time inputs to a human readable format.\n//\n// Size inputs are expected to be integers, and are formatted as a\n// byte size, such as \"83 MB\".\n//\n// Time inputs are parsed using the given layout (default layout is RFC1123Z)\n// and are formatted as a relative time, such as \"2 weeks ago\".\n// See https://pkg.go.dev/time#pkg-constants for time layout docs.\nfunc (c TemplateContext) funcHumanize(formatType, data string) (string, error) {\n\t// The format type can optionally be followed\n\t// by a colon to provide arguments for the format\n\tparts := strings.Split(formatType, \":\")\n\n\tswitch parts[0] {\n\tcase \"size\":\n\t\tdataint, dataerr := strconv.ParseUint(data, 10, 64)\n\t\tif dataerr != nil {\n\t\t\treturn \"\", fmt.Errorf(\"humanize: size cannot be parsed: %s\", dataerr.Error())\n\t\t}\n\t\treturn humanize.Bytes(dataint), nil\n\n\tcase \"time\":\n\t\ttimelayout := time.RFC1123Z\n\t\tif len(parts) > 1 {\n\t\t\ttimelayout = parts[1]\n\t\t}\n\n\t\tdataint, dataerr := time.Parse(timelayout, data)\n\t\tif dataerr != nil {\n\t\t\treturn \"\", fmt.Errorf(\"humanize: time cannot be parsed: %s\", dataerr.Error())\n\t\t}\n\t\treturn humanize.Time(dataint), nil\n\t}\n\n\treturn \"\", fmt.Errorf(\"no know function was given\")\n}","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/templates/tplcontext.go#L466-L502","documentation":"Returned by the templates module's humanize function, format 'size', when the argument cannot be parsed as an unsigned 64-bit integer (strconv.ParseUint fails). The value is then passed to humanize.Bytes to render like '1.5 MB'.","triggerScenarios":"{{ humanize \"size\" \"12.5\" }} (float), {{ humanize \"size\" \"-1\" }} (negative), {{ humanize \"size\" \"1_000\" }} or any non-numeric string such as an empty placeholder result.","commonSituations":"Feeding a float-formatted size from a template variable, a placeholder that resolves to empty when a header is missing, or sizes copied from human-readable strings ('10KB') instead of raw byte counts.","solutions":["Pass a raw non-negative integer byte count: {{ humanize \"size\" \"1500000\" }}","Pipe through placeholders that yield integers, e.g. {{ humanize \"size\" (printf \"%d\" .Size) }}","Default empty values first: {{ default \"0\" .Size }} before humanizing","Pre-format floats to integers in the template (printf '%.0f')"],"exampleFix":"<!-- before -->\n{{ humanize \"size\" \"12.5\" }}\n\n<!-- after -->\n{{ humanize \"size\" \"13\" }}","handlingStrategy":"validation","validationCode":"{{ $size := default \"0\" .Size }}{{ $size := printf \"%.0f\" (parseFloat $size) }}{{ humanize \"size\" $size }}","typeGuard":"{{ if and (ne .Size \"\") (not (strings.Contains .Size \".\")) (not (strings.HasPrefix .Size \"-\")) }}{{ humanize \"size\" .Size }}{{ end }}","tryCatchPattern":null,"preventionTips":["Normalize sizes to non-negative integers before humanize","Default empty placeholders to 0 upstream of the template","Unit-test templates with edge-case sizes (empty, float, negative)"],"tags":["caddy","templates","humanize","parsing"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}