{"record":{"id":"06027571ba2d8ab4","repo":"thanos-io/thanos","slug":"failed-to-parse-s-as-json-q","errorCode":null,"errorMessage":"failed to parse %s as JSON: %q","messagePattern":"failed to parse (.+?) as JSON: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/shipper/shipper.go","lineNumber":658,"sourceCode":"\tif err := f.Sync(); err != nil {\n\t\treturn err\n\t}\n\tif err := f.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn renameFile(logger, tmp, path)\n}\n\n// ReadMetaFile reads the given meta from <dir>/thanos.shipper.json.\nfunc ReadMetaFile(path string) (*Meta, error) {\n\tb, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to read %s\", path)\n\t}\n\n\tvar m Meta\n\tif err := json.Unmarshal(b, &m); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to parse %s as JSON: %q\", path, string(b))\n\t}\n\tif m.Version != MetaVersion1 {\n\t\treturn nil, errors.Errorf(\"unexpected meta file version %d\", m.Version)\n\t}\n\n\treturn &m, nil\n}\n\nfunc renameFile(logger log.Logger, from, to string) error {\n\tif err := os.RemoveAll(to); err != nil {\n\t\treturn err\n\t}\n\tif err := os.Rename(from, to); err != nil {\n\t\treturn err\n\t}\n\n\t// Directory was renamed; sync parent dir to persist rename.\n\tpdir, err := fileutil.OpenDir(filepath.Dir(to))","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/shipper/shipper.go#L640-L676","documentation":"ReadMetaFile parses a shipper meta file (JSON) from disk and wraps any json.Unmarshal failure with this message, including the file path and raw content. It is thrown because the meta file bytes are not valid JSON (or not decodable into shipper.Meta), so the shipper cannot determine which blocks were uploaded.","triggerScenarios":"Calling shipper.ReadMetaFile (directly or via Sync, AreAllBlocksUploaded, UploadedBlocks) when the meta.json file at `path` contains malformed JSON, empty bytes, or a structurally incompatible JSON document.","commonSituations":"Truncated meta file after a crash/power loss mid-write; manually edited meta.json with a typo; file written by an incompatible older/newer format; filesystem corruption; reading a directory or lock file by mistake instead of the meta file.","solutions":["Inspect the file contents (`cat <path>`) and fix or regenerate the corrupted meta.json.","Delete the corrupt meta file and re-run the shipper Sync so it recreates meta state from the object store.","Verify the process writing the meta file completes writes atomically (write to temp file then rename) to prevent truncation.","Check disk health and available space if corruption recurs."],"exampleFix":"// before\nm, err := shipper.ReadMetaFile(path)\n// after\nif _, err := os.Stat(path); err != nil { return err }\nb, _ := os.ReadFile(path)\nif !json.Valid(b) {\n    // regenerate or restore meta file before parsing\n    return fmt.Errorf(\"meta file %s is not valid JSON\", path)\n}\nm, err := shipper.ReadMetaFile(path)","handlingStrategy":"validation","validationCode":"b, err := os.ReadFile(path)\nif err != nil { return err }\nif !json.Valid(b) {\n    return fmt.Errorf(\"meta file %s is not valid JSON; regenerate or delete it\", path)\n}","typeGuard":null,"tryCatchPattern":"m, err := shipper.ReadMetaFile(path)\nif err != nil {\n    var corrupted = strings.Contains(err.Error(), \"as JSON\")\n    if corrupted {\n        // delete/regenerate meta and retry\n    }\n    return err\n}","preventionTips":["Write meta files atomically (temp file + rename).","Never hand-edit meta.json while the shipper runs.","Monitor disks for full/corrupt conditions.","Back up meta files before upgrades."],"tags":["json","file-parsing","shipper","corruption"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}