{"record":{"id":"aa8808fee0d0a702","repo":"JuliusBrussee/caveman","slug":"telemetry-attribute-q-exceeds-d-bytes","errorCode":null,"errorMessage":"telemetry attribute %q exceeds %d bytes","messagePattern":"telemetry attribute %q exceeds (.+?) bytes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/telemetry/span.go","lineNumber":268,"sourceCode":"\tkeys := make([]string, 0, len(attrs))\n\tfor key := range attrs {\n\t\tif AttributeAllowed(key) {\n\t\t\tkeys = append(keys, key)\n\t\t}\n\t}\n\tif len(keys) > MaxAttributes {\n\t\treturn nil, fmt.Errorf(\"telemetry attributes exceed %d keys\", MaxAttributes)\n\t}\n\tsort.Strings(keys)\n\tout := make(map[string]string, len(keys))\n\ttotal := 0\n\tfor _, key := range keys {\n\t\tvalue := attrs[key]\n\t\tif len(key) > MaxAttributeKeyBytes {\n\t\t\treturn nil, fmt.Errorf(\"telemetry attribute key exceeds %d bytes\", MaxAttributeKeyBytes)\n\t\t}\n\t\tif len(value) > MaxAttributeValueBytes {\n\t\t\treturn nil, fmt.Errorf(\"telemetry attribute %q exceeds %d bytes\", key, MaxAttributeValueBytes)\n\t\t}\n\t\ttotal += len(key) + len(value)\n\t\tif total > MaxAttributesBytes {\n\t\t\treturn nil, fmt.Errorf(\"telemetry attributes exceed %d bytes\", MaxAttributesBytes)\n\t\t}\n\t\tout[key] = value\n\t}\n\treturn out, nil\n}\n","sourceCodeStart":250,"sourceCodeEnd":278,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/telemetry/span.go#L250-L278","documentation":"SanitizeAttributes enforces per-value and total byte budgets for span attributes. This specific error fires when a single attribute value exceeds MaxAttributeValueBytes; a sibling error covers the aggregate total exceeding MaxAttributesBytes. It fails closed rather than truncating the value.","triggerScenarios":"Parse called on a span where attrs[key] has a byte length greater than MaxAttributeValueBytes — e.g. dumping an entire HTTP response body, stack trace, or serialized JSON payload into one attribute.","commonSituations":"Recording full request/response bodies as attributes; storing large exception stack traces; accidentally passing an entire config blob instead of a summary.","solutions":["Truncate the value before setting it (e.g. cap at 256 bytes with an ellipsis marker).","Store a digest/ID and keep the full payload in logs or object storage.","Split oversized payloads across dedicated log events rather than span attributes.","Audit instrumentation for places that serialize whole objects into attribute values."],"exampleFix":"// before\nattrs[\"http.response.body\"] = string(fullResponseBody) // often > limit\n\n// after\nbody := string(fullResponseBody)\nif len(body) > 256 { body = body[:256] + \"...[truncated]\" }\nattrs[\"http.response.body\"] = body","handlingStrategy":"validation","validationCode":"for k, v := range attrs {\n    if len(v) > maxAttrValueBytes /* mirror MaxAttributeValueBytes */ {\n        attrs[k] = truncate(v, maxAttrValueBytes)\n    }\n}","typeGuard":null,"tryCatchPattern":"sanitized, err := telemetry.SanitizeAttributes(raw)\nif err != nil && strings.Contains(err.Error(), \"exceeds\") && strings.Contains(err.Error(), \"bytes\") {\n    raw = truncateValues(raw, maxAttrValueBytes)\n    sanitized, err = telemetry.SanitizeAttributes(raw)\n}","preventionTips":["Truncate large payloads (bodies, stack traces) at capture time, with an explicit marker.","Store references (IDs, log keys) instead of full payloads in attributes.","Also mind the aggregate MaxAttributesBytes budget across all key/value pairs.","Add unit tests asserting attribute sizes stay under limits."],"tags":["telemetry","attributes","limits","payload-size"],"backgroundTag":"payload-too-large","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}