{"record":{"id":"0ab5e4d70fe35561","repo":"cloudflare/cloudflared","slug":"expected-disk-volume-to-have-d-fields-got-d-w","errorCode":null,"errorMessage":"expected disk volume to have %d fields got %d: %w","messagePattern":"expected disk volume to have (.+?) fields got (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"diagnostic/system_collector_utils.go","lineNumber":87,"sourceCode":"\t\tsizeCurrentField  = 2\n\t)\n\n\tdisksRaw := strings.Split(output, \"\\n\")\n\tdisks := make([]*DiskVolumeInformation, 0)\n\n\tif skipLines > len(disksRaw) || skipLines < 0 {\n\t\tskipLines = 0\n\t}\n\n\tfor _, disk := range disksRaw[skipLines:] {\n\t\tif disk == \"\" {\n\t\t\t// skip empty line\n\t\t\tcontinue\n\t\t}\n\n\t\tfields := strings.Fields(disk)\n\t\tif len(fields) < diskFieldsMinimum {\n\t\t\treturn nil, fmt.Errorf(\"expected disk volume to have %d fields got %d: %w\",\n\t\t\t\tdiskFieldsMinimum, len(fields), ErrInsuficientFields,\n\t\t\t)\n\t\t}\n\n\t\tname := fields[nameField]\n\n\t\tsizeMaximum, err := strconv.ParseUint(fields[sizeMaximumField], 10, 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tsizeCurrent, err := strconv.ParseUint(fields[sizeCurrentField], 10, 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tdiskInfo := NewDiskVolumeInformation(\n\t\t\tname, uint64(float64(sizeMaximum)*scale), uint64(float64(sizeCurrent)*scale),","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/diagnostic/system_collector_utils.go#L69-L105","documentation":"ParseDiskVolumeInformationOutput validates that each line of `df`-style disk volume output contains at least `diskFieldsMinimum` whitespace-separated fields. When a line is too sparse it returns ErrInsuficientFields wrapped in this message, since fields like device name and mount point cannot be extracted reliably from a malformed line.","triggerScenarios":"Calling ParseDiskVolumeInformationOutput (directly or via collectDiskVolumeInformationUnix/collectDiskVolumeInformation during Collect) with df output whose header line or a truncated line has fewer fields than diskFieldsMinimum — e.g. parsing df output that still includes the 'Filesystem ... Mount on' header, or a locale producing extra/short lines.","commonSituations":"Forgetting `df -P` style normalization so wrapped device names split across lines, localized df headers/columns on non-English systems, empty or partial output when the disk is unavailable, or feeding the function raw output that includes blank or banner lines.","solutions":["Strip the df header line before parsing (skip the first line or filter lines starting with 'Filesystem').","Call df with portable flags (e.g. `df -P -k`) so every data line has the standard 6 columns.","Check the df output on the failing host for line wrapping — use longer device-name output or `-P` to prevent wraps.","Set LC_ALL=C when invoking df to avoid locale-dependent column variations."],"exampleFix":"// before\nout, _ := exec.Command(\"df\").Output()\ninfo, err := diagnostic.ParseDiskVolumeInformationOutput(string(out))\n// after\nout, _ := exec.Command(\"df\", \"-P\", \"-k\").Output()\nlines := strings.Split(string(out), \"\\n\")\nif len(lines) > 0 {\n\tlines = lines[1:] // drop header\n}\ninfo, err := diagnostic.ParseDiskVolumeInformationOutput(strings.Join(lines, \"\\n\"))","handlingStrategy":"validation","validationCode":"func validateDiskOutput(output string) error {\n\tfor _, line := range strings.Split(output, \"\\n\") {\n\t\tline = strings.TrimSpace(line)\n\t\tif line == \"\" || strings.HasPrefix(line, \"Filesystem\") {\n\t\t\tcontinue\n\t\t}\n\t\tif len(strings.Fields(line)) < 6 {\n\t\t\treturn fmt.Errorf(\"disk line too short: %q\", line)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"info, err := diagnostic.ParseDiskVolumeInformationOutput(dfOutput)\nvar target error = diagnostic.ErrInsuficientFields\nif errors.Is(err, target) {\n\tlog.Warn().Msg(\"skipping malformed disk volume line\")\n} else if err != nil {\n\treturn fmt.Errorf(\"disk parse failed: %w\", err)\n}","preventionTips":["Always invoke df with -P (POSIX) so lines never wrap and have a fixed column count.","Strip the header line before parsing.","Set LC_ALL=C on df invocations to avoid locale-dependent output.","Pre-validate field counts per line before feeding output to the parser."],"tags":["parsing","disk","diagnostics","unix"],"backgroundTag":"unexpected-response-shape","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}