{"record":{"id":"f397b0ec145536e6","repo":"jaegertracing/jaeger","slug":"failed-to-marshal-slice-attribute-q-w","errorCode":null,"errorMessage":"failed to marshal slice attribute %q: %w","messagePattern":"failed to marshal slice attribute %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/v2/clickhouse/tracestore/query_builder.go","lineNumber":245,"sourceCode":"\tq.WriteString(\"OR\")\n\tappendArrayExists(q, 2, \"scope\", valueType)\n\tappendNewlineAndIndent(q, 2)\n\tq.WriteString(\"OR\")\n\tappendNestedArrayExists(q, 2, \"events\", valueType)\n\tappendNewlineAndIndent(q, 2)\n\tq.WriteString(\"OR\")\n\tappendNestedArrayExists(q, 2, \"links\", valueType)\n\treturn append(args, key, value, key, value, key, value, key, value, key, value)\n}\n\nfunc buildBytesAttributeCondition(q *strings.Builder, args []any, key string, attr pcommon.Value) []any {\n\treturn buildSimpleAttributeCondition(q, args, \"@bytes@\"+key, pcommon.ValueTypeBytes, base64.StdEncoding.EncodeToString(attr.Bytes().AsRaw()))\n}\n\nfunc buildSliceAttributeCondition(q *strings.Builder, args []any, key string, attr pcommon.Value) ([]any, error) {\n\tb, err := marshalValueForQuery(attr)\n\tif err != nil {\n\t\treturn args, fmt.Errorf(\"failed to marshal slice attribute %q: %w\", key, err)\n\t}\n\treturn buildSimpleAttributeCondition(q, args, \"@slice@\"+key, pcommon.ValueTypeSlice, b), nil\n}\n\nfunc buildMapAttributeCondition(q *strings.Builder, args []any, key string, attr pcommon.Value) ([]any, error) {\n\tb, err := marshalValueForQuery(attr)\n\tif err != nil {\n\t\treturn args, fmt.Errorf(\"failed to marshal map attribute %q: %w\", key, err)\n\t}\n\treturn buildSimpleAttributeCondition(q, args, \"@map@\"+key, pcommon.ValueTypeMap, b), nil\n}\n\nfunc parseStringToTypedValue(key string, attr pcommon.Value, t pcommon.ValueType) (typedAttributeValue, error) {\n\tswitch t {\n\tcase pcommon.ValueTypeBool:\n\t\tb, parseErr := strconv.ParseBool(attr.Str())\n\t\tif parseErr != nil {\n\t\t\treturn typedAttributeValue{}, fmt.Errorf(\"failed to parse bool attribute %q: %w\", key, parseErr)","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/v2/clickhouse/tracestore/query_builder.go#L227-L263","documentation":"buildSliceAttributeCondition serializes a slice-typed attribute via marshalValueForQuery before embedding it in the SQL condition. If marshaling fails, the error is wrapped with the attribute key so the failing attribute can be identified.","triggerScenarios":"A query includes a slice attribute whose contents cannot be marshaled for the ClickHouse query — e.g. nested values of unsupported types inside the slice.","commonSituations":"Query attributes built from arbitrary OTLP payloads containing deeply nested or heterogeneous slice values; malformed pcommon.Value slices constructed programmatically.","solutions":["Inspect the wrapped marshal error to find the unserializable element","Normalize the slice attribute to homogeneous, supported element types before querying","Avoid passing deeply nested slices; flatten or convert to JSON-friendly values","Add a pre-validation step that marshals query attributes before issuing the search"],"exampleFix":"// before: slice containing a map element fails to marshal\nvals := pcommon.NewValueSlice(); vals.SliceVal().AppendEmpty().SetEmptyMap()\n// after: use flat scalar slices\nvals.SliceVal().AppendEmpty().SetInt(42)","handlingStrategy":"validation","validationCode":"b, err := json.Marshal(attr.AsRaw())\nif err != nil {\n    return fmt.Errorf(\"slice attribute %q is not serializable: %w\", key, err)\n}","typeGuard":"func isFlatSlice(v pcommon.Value) bool {\n    if v.Type() != pcommon.ValueTypeSlice { return false }\n    ok := true\n    v.Slice().Range(func(_ pcommon.Value) bool {\n        return ok\n    })\n    for i := 0; i < v.Slice().Len(); i++ {\n        t := v.Slice().At(i).Type()\n        if t == pcommon.ValueTypeMap || t == pcommon.ValueTypeSlice {\n            ok = false\n        }\n    }\n    return ok\n}","tryCatchPattern":"traceIDs, err := store.FindTraceIDs(ctx, query)\nif err != nil && strings.Contains(err.Error(), \"failed to marshal slice attribute\") {\n    log.Warn(\"unserializable slice attribute in query\", \"err\", err)\n    return err\n}","preventionTips":["Use homogeneous scalar slices in search attributes","Flatten nested structures before building queries","Test attribute marshaling in unit tests for all query paths"],"tags":["clickhouse","serialization","attributes","query-builder"],"backgroundTag":"attribute-serialization-failed","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}