{"record":{"id":"9417b42b1e67a9e2","repo":"amir20/dozzle","slug":"invalid-format-key-is-empty","errorCode":null,"errorMessage":"invalid format: key is empty","messagePattern":"invalid format: key is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"info","filePath":"internal/container/logfmt.go","lineNumber":23,"sourceCode":"\t\"strconv\"\n\t\"strings\"\n\n\torderedmap \"github.com/wk8/go-ordered-map/v2\"\n)\n\n// ParseLogFmt parses a log entry in logfmt format and returns a map of key-value pairs.\nfunc ParseLogFmt(log string) (*orderedmap.OrderedMap[string, string], error) {\n\tresult := orderedmap.New[string, string]()\n\tvar key, value string\n\tinQuotes, escaping, isKey := false, false, true\n\tstart := 0\n\n\tfor i := 0; i < len(log); i++ {\n\t\tchar := log[i]\n\t\tif isKey {\n\t\t\tif char == '=' {\n\t\t\t\tif start >= i {\n\t\t\t\t\treturn nil, errors.New(\"invalid format: key is empty\")\n\t\t\t\t}\n\t\t\t\tkey = log[start:i]\n\t\t\t\tisKey = false\n\t\t\t\tstart = i + 1\n\t\t\t} else if char == ' ' {\n\t\t\t\tif i > start {\n\t\t\t\t\treturn nil, errors.New(\"invalid format: unexpected space in key\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\tif inQuotes {\n\t\t\t\tif escaping {\n\t\t\t\t\tescaping = false\n\t\t\t\t} else if char == '\\\\' {\n\t\t\t\t\tescaping = true\n\t\t\t\t} else if char == '\"' {\n\t\t\t\t\tvalue = unescapeQuoted(log[start-1 : i+1])","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/amir20/dozzle/blob/d9463cbe21874e44ab79db6fa63e746ca7d22928/internal/container/logfmt.go#L5-L41","documentation":"ParseLogFmt in internal/container/logfmt.go parses logfmt-style lines (key=value pairs). It raises 'invalid format: key is empty' when it encounters '=' while isKey is true with start >= i, i.e. there is no non-empty key before the '=' sign. It returns nil along with the error, aborting parsing of that line.","triggerScenarios":"A log line containing '=value', ' =value', or a leading '=value' segment, or two consecutive spaces before '=' collapse into an empty key (start == i at the '=').","commonSituations":"Application logs emit lines like '=foo' or a message beginning with '=' (e.g. '== Marker =='), or logfmt detection misfires on non-logfmt text; hand-rolled log lines with missing keys ('=error level=3').","solutions":["Fix the producing application so every key=value pair has a non-empty key","Strip or quote message text starting with '=' so it isn't parsed as a logfmt key","Treat parse failure as fallback: log the line as a plain SimpleLogEntry instead of structured fields","If you control parsing, skip empty keys and continue parsing the remainder of the line rather than failing"],"exampleFix":"// before\nif start >= i {\n    return nil, errors.New(\"invalid format: key is empty\")\n}\n// after: skip malformed segment, keep parsing\nif start >= i {\n    isKey = false\n    start = i + 1\n    continue\n}","handlingStrategy":"fallback","validationCode":"if (/^\\s*=/.test(line) || /(^|\\s)=/.test(line)) {\n  // not valid logfmt; render as plain text instead of calling ParseLogFmt\n}","typeGuard":"func looksLikeLogFmt(line string) bool {\n    return strings.Contains(line, \"=\") && !strings.HasPrefix(strings.TrimSpace(line), \"=\")\n}","tryCatchPattern":"fields, err := ParseLogFmt(line)\nif err != nil {\n    event.Message = line // fall back to plain-text log entry\n} else {\n    event.Fields = fields\n}","preventionTips":["Fall back to a plain-text entry on parse failure instead of dropping the line","Fix the emitting application to never produce empty keys (=value)","Quote message text starting with '=' in your logger","Unit-test ParseLogFmt with lines containing leading '=' and double spaces"],"tags":["logfmt","parsing","go","format-validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"d9463cbe21874e44ab79db6fa63e746ca7d22928","analyzedAt":"2026-09-07T10:08:55.855Z","contentChangedAt":"2026-09-07T10:08:55.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}