{"record":{"id":"93eb12a0f2eb4076","repo":"thanos-io/thanos","slug":"read-convertedfromblids-field-from-parquet-metadat","errorCode":null,"errorMessage":"read convertedFromBLIDs field from parquet metadata file: %v","messagePattern":"read convertedFromBLIDs field from parquet metadata file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/fetcher.go","lineNumber":1250,"sourceCode":"\t}\n\tdefer runutil.CloseWithLogOnErr(f.logger, r, \"close bkt get\")\n\n\tcontent, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"read parquet metadata file: %v\", path)\n\t}\n\n\tvar fc easyproto.FieldContext\n\tfor len(content) > 0 {\n\t\tcontent, err = fc.NextField(content)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"read next field from parquet metadata file: %v\", path)\n\t\t}\n\t\tswitch fc.FieldNum {\n\t\tcase 6:\n\t\t\tu, ok := fc.String()\n\t\t\tif !ok {\n\t\t\t\treturn nil, errors.Wrapf(err, \"read convertedFromBLIDs field from parquet metadata file: %v\", path)\n\t\t\t}\n\t\t\tid, err := ulid.Parse(u)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrapf(err, \"parse block ID %q from parquet metadata file: %v\", u, path)\n\t\t\t}\n\t\t\tmigratedBlocks[id] = struct{}{}\n\t\t}\n\t}\n\n\treturn migratedBlocks, nil\n}\n\n// IgnoreDeletionMarkFilter is a filter that filters out the blocks that are marked for deletion after a given delay.\n// The delay duration is to make sure that the replacement block can be fetched before we filter out the old block.\n// Delay is not considered when computing DeletionMarkBlocks map.\n// Not go-routine safe.\ntype IgnoreDeletionMarkFilter struct {\n\tlogger      log.Logger","sourceCodeStart":1232,"sourceCodeEnd":1268,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/fetcher.go#L1232-L1268","documentation":"Returned when field 6 (convertedFromBLIDs) of the parquet metadata protobuf message is present but fc.String() returns !ok — i.e. the field's wire type is not a string/bytes field as expected. Note the code wraps the (usually nil) err, so the wrap message carries the path but no underlying cause.","triggerScenarios":"A parquet metadata file whose field 6 is encoded with an unexpected wire type (varint/fixed instead of length-delimited) — produced by a schema mismatch or a corrupt/truncated file.","commonSituations":"Parquet converter version writing a different proto schema for field 6; manually edited or corrupted metadata files.","solutions":["Regenerate the parquet metadata with a matching converter version","Check whether the converter's proto definition changed field 6's type; align reader/writer versions","Delete the offending metadata file if it is unrecoverable"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isStringField(fc *easyproto.FieldContext) bool {\n    return fc.FieldNum == 6 && fc.String() != nil\n}","tryCatchPattern":"u, ok := fc.String()\nif !ok { return fmt.Errorf(\"field 6 of %s is not a string\", path) }","preventionTips":["Pin converter and reader to compatible versions","Regenerate metadata after proto schema changes","Validate written files with a round-trip decode test","Never hand-edit parquet metadata files"],"tags":["protobuf","parquet","wire-type"],"backgroundTag":"protobuf-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"}