{"record":{"id":"1c54e7c4308d5898","repo":"AlexxIT/go2rtc","slug":"errread","errorCode":"ErrRead","errorMessage":"amf: read error","messagePattern":"amf: read error","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/flv/amf/amf.go","lineNumber":25,"sourceCode":")\n\nconst (\n\tTypeNumber byte = iota\n\tTypeBoolean\n\tTypeString\n\tTypeObject\n\tTypeNull      = 5\n\tTypeEcmaArray = 8\n\tTypeObjectEnd = 9\n)\n\n// AMF spec: http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf\ntype AMF struct {\n\tbuf []byte\n\tpos int\n}\n\nvar ErrRead = errors.New(\"amf: read error\")\n\nfunc NewReader(b []byte) *AMF {\n\treturn &AMF{buf: b}\n}\n\nfunc (a *AMF) ReadItems() ([]any, error) {\n\tvar items []any\n\tfor a.pos < len(a.buf) {\n\t\tv, err := a.ReadItem()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\titems = append(items, v)\n\t}\n\treturn items, nil\n}\n\nfunc (a *AMF) ReadItem() (any, error) {","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/flv/amf/amf.go#L7-L43","documentation":"amf.ErrRead (\"amf: read error\", pkg/flv/amf/amf.go:25) is the sentinel returned by the AMF0 reader (ReadItem, ReadByte, ReadNumber, ReadString, ReadEcmaArray) when a read would go past the end of the buffer (a.pos >= len(a.buf)) or an item cannot be parsed. It indicates truncated or malformed AMF data, typically a corrupt FLV tag payload.","triggerScenarios":"Any AMF decode call (ReadItems/ReadItem/ReadByte/ReadNumber/ReadString/ReadEcmaArray) on a buffer shorter than the encoded item requires, or a malformed item (e.g. ReadItem at amf.go:73 hitting an unknown/invalid type marker and falling through to return ErrRead).","commonSituations":"Truncated FLV tag due to a dropped connection mid-tag; corrupt recording file; parsing an FLV tag payload that isn't AMF (e.g. feeding metadata into the wrong decoder); producer emitting a non-standard AMF type marker the reader doesn't implement.","solutions":["Check for truncation upstream: ensure the FLV tag payload was fully read before AMF decoding.","Validate the source stream/file integrity; resync or reconnect if the producer truncated the tag.","Wrap decodes with errors.Is(err, amf.ErrRead) and skip the malformed tag instead of aborting the whole stream.","Log the raw buffer and type marker; an unimplemented AMF0 type requires extending the reader.","If reading a file, verify it isn't a partial download/corrupt recording."],"exampleFix":"// before\nitems, err := amf.NewReader(tag.Payload).ReadItems()\nif err != nil {\n    return err // whole pipeline dies on one bad tag\n}\n// after\nitems, err := amf.NewReader(tag.Payload).ReadItems()\nif errors.Is(err, amf.ErrRead) {\n    log.Warn(\"skipping malformed AMF tag\")\n    return nil\n}","handlingStrategy":"try-catch","validationCode":"// ensure the payload is long enough to hold at least one AMF item\nif len(tag.Payload) < 2 {\n    return nil // nothing decodable\n}","typeGuard":"func isAMFReadError(err error) bool {\n    return errors.Is(err, amf.ErrRead)\n}","tryCatchPattern":"items, err := amf.NewReader(payload).ReadItems()\nif errors.Is(err, amf.ErrRead) {\n    log.Warn(\"malformed AMF data; skipping tag\")\n    return nil\n}","preventionTips":["Fully read FLV tags before decoding their AMF payload","Skip (don't abort on) individual malformed tags in live streams","Validate recording files for truncation before parsing","Check for unknown AMF0 type markers if errors are consistent"],"tags":["flv","amf","parsing","media","sentinel-error"],"backgroundTag":"unexpected-response-shape","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}