{"record":{"id":"dfa1755b4868b4c4","repo":"benbjohnson/litestream","slug":"invalid-level-in-path-s-w","errorCode":null,"errorMessage":"invalid level in path %s: %w","messagePattern":"invalid level in path (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nats/replica_client.go","lineNumber":269,"sourceCode":"\treturn litestream.LTXFilePath(c.Path, level, minTXID, maxTXID)\n}\n\n// parseLTXPath parses an LTX object path and returns level, minTXID, and maxTXID.\nfunc (c *ReplicaClient) parseLTXPath(objPath string) (level int, minTXID, maxTXID ltx.TXID, err error) {\n\t// Remove the base path prefix if present\n\tif c.Path != \"\" && strings.HasPrefix(objPath, c.Path+\"/\") {\n\t\tobjPath = strings.TrimPrefix(objPath, c.Path+\"/\")\n\t}\n\n\t// Expected format: \"ltx/<level>/<minTXID>-<maxTXID>.ltx\"\n\tparts := strings.Split(objPath, \"/\")\n\tif len(parts) < 3 || parts[0] != \"ltx\" {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid ltx path: %s\", objPath)\n\t}\n\n\t// Parse level\n\tif level, err = strconv.Atoi(parts[1]); err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid level in path %s: %w\", objPath, err)\n\t}\n\n\t// Parse filename (minTXID-maxTXID.ltx)\n\tfilename := parts[2]\n\tminTXIDVal, maxTXIDVal, err := ltx.ParseFilename(filename)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid filename in path %s: %w\", objPath, err)\n\t}\n\n\treturn level, minTXIDVal, maxTXIDVal, nil\n}\n\n// LTXFiles returns an iterator of all LTX files on the replica for a given level.\n// NATS always uses accurate timestamps from headers since they're included in LIST operations at zero cost.\n// The useMetadata parameter is ignored.\nfunc (c *ReplicaClient) LTXFiles(ctx context.Context, level int, seek ltx.TXID, useMetadata bool) (ltx.FileIterator, error) {\n\tif err := c.Init(ctx); err != nil {\n\t\treturn nil, err","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/nats/replica_client.go#L251-L287","documentation":"After confirming the key layout, parseLTXPath parses parts[1] as the compaction level integer; this error wraps strconv.Atoi failures. It means the second path segment is not a valid decimal level (e.g. garbage, empty string, or the config path prefix was not stripped so the segment is not the level at all).","triggerScenarios":"LTXFiles → parseLTXPath where the level segment fails strconv.Atoi: keys like `ltx/abc/...`, empty segment (`ltx//...`), or unstripped prefixes shifting the segments (`litestream/ltx/0/...` with an unset Path prefix).","commonSituations":"Same root causes as invalid ltx path: shared buckets, wrong `path` prefix config, manually uploaded/corrupted keys; also negative or oversized level values that represent a config prefix bug.","solutions":["Check the offending key: the level segment must be a decimal integer (e.g. ltx/0/...)\nSet the `path` config option so the extra prefix is stripped before parsing\nRemove or quarantine non-litestream objects in the bucket\nRe-seed the replica with a fresh full backup if keys are corrupt"],"exampleFix":"// key: litestream/ltx/0/... with no path configured -> level=\"litestream\"? actually parses level from wrong segment\n// before\nurl: \"nats://host:4222/backups\"\n// after\npath: \"litestream\"\nurl: \"nats://host:4222/backups\"","handlingStrategy":"validation","validationCode":"level, err := strconv.Atoi(parts[1])\nif err != nil {\n\tlog.Printf(\"object %q has non-numeric level segment %q; check path prefix config\", key, parts[1])\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the `path` config prefix matches how objects were written","Expect exactly one numeric level segment: ltx/<level>/<min>-<max>.ltx","Clean up manually created or legacy-named objects in the bucket"],"tags":["nats","ltx","path-parsing","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}