{"record":{"id":"873e6cebdcc97a8c","repo":"containerd/containerd","slug":"failed-to-parse-output-q","errorCode":null,"errorMessage":"failed to parse output: %q","messagePattern":"failed to parse output: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/snapshots/devmapper/dmsetup/dmsetup.go","lineNumber":311,"sourceCode":"\t\terr    error\n\t\tstatus DeviceStatus\n\t)\n\n\toutput, err := dmsetup(\"status\", deviceName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatus.RawOutput = output\n\n\t// Status output format:\n\t//  Offset (int64)\n\t//  Length (int64)\n\t//  Target type (string)\n\t//  Params (Array of strings)\n\tconst MinParseCount = 4\n\tparts := strings.Split(output, \" \")\n\tif len(parts) < MinParseCount {\n\t\treturn nil, fmt.Errorf(\"failed to parse output: %q\", output)\n\t}\n\n\tstatus.Offset, err = strconv.ParseInt(parts[0], 10, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse offset: %q: %w\", parts[0], err)\n\t}\n\n\tstatus.Length, err = strconv.ParseInt(parts[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse length: %q: %w\", parts[1], err)\n\t}\n\n\tstatus.Target = parts[2]\n\tstatus.Params = parts[3:]\n\n\treturn &status, nil\n}\n","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/plugins/snapshots/devmapper/dmsetup/dmsetup.go#L293-L329","documentation":"Status() parses `dmsetup status` output, which must contain at least 4 space-separated fields (offset, length, target type, params). This error is thrown when the output has fewer fields, meaning the status line is malformed or not a valid table status.","triggerScenarios":"Status -> GetUsage or createSnapshot receives truncated or unexpected `dmsetup status` output: device not yet activated, error line from dmsetup, or empty output passed to the parser.","commonSituations":"Querying a device before it is created/activated; dmsetup reporting an error state whose status line has a different shape; version mismatch changing column count.","solutions":["Run `dmsetup status <name>` manually to see the actual output shape.","Ensure the thin-pool/device is created and activated before querying status.","Treat a missing device as a distinct case: check Info() first or handle exit codes from dmsetup.","Confirm dmsetup version compatibility with the expected 4+-field status format.","Check the wrapped dmsetup exec error path — stderr may explain why the output is malformed."],"exampleFix":"// before\nusage, err := pool.GetUsage() // device not activated yet\n// after\ninfo, err := devInfo() // wrap dmsetup Info\nif err != nil || !info.TableLive { return nil, fmt.Errorf(\"device %s not active\", name) }\nusage, err := pool.GetUsage()","handlingStrategy":"validation","validationCode":"func ensureDeviceActive(name string) error {\n    out, err := exec.Command(\"dmsetup\", \"info\", name).Output()\n    if err != nil { return err }\n    return nil // exists; proceed to status\n}\n// call ensureDeviceActive before Status/GetUsage","typeGuard":null,"tryCatchPattern":"usage, err := pool.GetUsage()\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to parse output\") {\n        return fmt.Errorf(\"device not active or status malformed; run 'dmsetup status %s' to inspect: %w\", name, err)\n    }\n    return err\n}","preventionTips":["Only query status for devices already created and activated","Check Info()/TableLive before Status","Handle dmsetup non-zero exit codes instead of parsing error text","Test parser changes against known-good `dmsetup status` samples"],"tags":["devmapper","dmsetup","parsing","status"],"backgroundTag":"dmsetup-output-parse-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}