{"record":{"id":"19fe1fc7f25f1c76","repo":"shadow1ng/fscan","slug":"result-cannot-be-nil","errorCode":null,"errorMessage":"result cannot be nil","messagePattern":"result cannot be nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/output/manager.go","lineNumber":81,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\n\tm.writer = writer\n\treturn m.writer.WriteHeader()\n}\n\n// SaveResult 保存扫描结果\nfunc (m *Manager) SaveResult(result *ScanResult) error {\n\tm.mu.RLock()\n\tdefer m.mu.RUnlock()\n\n\tif m.closed {\n\t\treturn fmt.Errorf(\"output manager is closed\")\n\t}\n\n\tif result == nil {\n\t\treturn fmt.Errorf(\"result cannot be nil\")\n\t}\n\n\treturn m.writer.Write(result)\n}\n\n// Flush 刷新输出\nfunc (m *Manager) Flush() error {\n\tm.mu.RLock()\n\tdefer m.mu.RUnlock()\n\n\tif m.closed {\n\t\treturn fmt.Errorf(\"output manager is closed\")\n\t}\n\n\treturn m.writer.Flush()\n}\n\n// Close 关闭输出管理器","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/output/manager.go#L63-L99","documentation":"Argument guard in Manager.SaveResult: the method was invoked with a nil *ScanResult, which cannot be serialized to any output writer. It is a programmer/API-contract error (caller passed nil), distinct from the 'output manager is closed' state check that precedes it.","triggerScenarios":"Passing nil to SaveResult, e.g. when a scan stage produced no result or an upstream function returned (nil, nil) and the caller forwards it unchecked.","commonSituations":"Pipeline code where a failed probe returns nil result without an error, appending nil in a results slice and flushing it, tests like TestManager_SaveNilResult.","solutions":["Check results for nil before calling SaveResult","Ensure scan functions return an error alongside nil results so callers can skip","Filter nil entries out of result slices before persisting"],"exampleFix":"// before\nmgr.SaveResult(res) // res may be nil\n// after\nif res != nil {\n    mgr.SaveResult(res)\n}","handlingStrategy":"type-guard","validationCode":"if res == nil {\n    return errors.New(\"no scan result to save\")\n}\nreturn mgr.SaveResult(res)","typeGuard":"func hasResult(r *ScanResult) bool { return r != nil }","tryCatchPattern":"if err := mgr.SaveResult(res); err != nil {\n    if strings.Contains(err.Error(), \"result cannot be nil\") {\n        log.Debug(\"skipping nil result\")\n        return nil\n    }\n    return err\n}","preventionTips":["Nil-check results before saving","Make scan functions return an error with nil results","Filter nil entries from slices before persisting"],"tags":["output","nil-check","validation"],"backgroundTag":"null-argument","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}