{"record":{"id":"ae6d28e4a1cca3a0","repo":"owasp-amass/amass","slug":"failed-to-unmarchal-the-json","errorCode":null,"errorMessage":"failed to unmarchal the JSON","messagePattern":"failed to unmarchal the JSON","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/afmt/slog.go","lineNumber":20,"sourceCode":"// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.\n// SPDX-License-Identifier: Apache-2.0\n\npackage afmt\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"strconv\"\n\t\"time\"\n)\n\nfunc JSONLogToRecord(logstr string) (slog.Record, error) {\n\tj := make(map[string]any)\n\t// unmarshal the log message sent from the engine session\n\tif err := json.Unmarshal([]byte(logstr), &j); err != nil {\n\t\treturn slog.Record{}, errors.New(\"failed to unmarchal the JSON\")\n\t}\n\n\tltime := time.Now()\n\tif timeVal, found := j[slog.TimeKey]; found {\n\t\tif timestr, valid := timeVal.(string); valid {\n\t\t\tif t, err := time.Parse(\"2006-01-02T15:04:05.000000000Z\", timestr); err == nil {\n\t\t\t\tltime = t\n\t\t\t}\n\t\t}\n\t}\n\tdelete(j, slog.TimeKey)\n\n\tvar level slog.Level\n\t// extract the log level for the new record\n\tif val, found := j[slog.LevelKey]; !found {\n\t\treturn slog.Record{}, errors.New(\"failed to find the level key\")\n\t} else if str, ok := val.(string); !ok {\n\t\treturn slog.Record{}, errors.New(\"failed to cast the level value\")","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/owasp-amass/amass/blob/79299dce87b0085db0f2f4ef3e9c52cccb49f514/internal/afmt/slog.go#L2-L38","documentation":"JSONLogToRecord converts a JSON-formatted log line emitted by the engine session into a slog.Record. If json.Unmarshal fails on the input string, the function cannot proceed and returns this generic error (note the typo 'unmarchal' in the message). It throws because a non-JSON or truncated line cannot be mapped to a structured record.","triggerScenarios":"WriteLogMessage receives a logstr that is not valid JSON: empty string, plain-text log line, partially written/truncated line from a broken pipe, or a line with a JSON-unrepresentable payload.","commonSituations":"Mixing human-readable and JSON log formats in the same stream; reading a line before the writer finished flushing; engine emitting a stack trace or multi-line message; encoding bugs upstream.","solutions":["Ensure the engine session writes one complete JSON object per line (JSON Lines format)","Validate the input with json.Valid([]byte(logstr)) before calling JSONLogToRecord and log raw lines that fail","Check for truncation — read full lines with a scanner and proper buffer size","Confirm the engine and the log consumer use the same serialization options (no HTML escaping or custom field differences that break parsing)"],"exampleFix":"// before\nif err := json.Unmarshal([]byte(logstr), &j); err != nil {\n    return slog.Record{}, errors.New(\"failed to unmarchal the JSON\")\n}\n// after\nif !json.Valid([]byte(logstr)) {\n    return slog.Record{}, fmt.Errorf(\"failed to unmarshal the JSON: %q\", logstr)\n}\nif err := json.Unmarshal([]byte(logstr), &j); err != nil {\n    return slog.Record{}, fmt.Errorf(\"failed to unmarshal the JSON: %w\", err)\n}","handlingStrategy":"validation","validationCode":"if !json.Valid([]byte(logstr)) {\n    // route to raw-log sink instead of JSONLogToRecord\n    return errors.New(\"not a JSON log line\")\n}","typeGuard":null,"tryCatchPattern":"rec, err := afmt.JSONLogToRecord(line)\nif err != nil {\n    if strings.Contains(err.Error(), \"unmarchal the JSON\") {\n        rawLog.Printf(\"non-JSON log line dropped: %q\", line)\n        return nil\n    }\n    return err\n}","preventionTips":["Write engine logs strictly in JSON Lines format (one object per line)","Use a bufio.Scanner with a large buffer to avoid truncated lines","Never interleave plain-text output with the JSON log stream","Add a unit test round-tripping representative engine log lines through JSONLogToRecord"],"tags":["logging","json","parsing"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"79299dce87b0085db0f2f4ef3e9c52cccb49f514","analyzedAt":"2026-09-06T08:22:48.198Z","contentChangedAt":"2026-09-06T08:22:48.198Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}