{"record":{"id":"8c4054426fdd06a6","repo":"sundowndev/phoneinfoga","slug":"panic-occurred-while-running-scan-see-debug-logs","errorCode":null,"errorMessage":"panic occurred while running scan, see debug logs","messagePattern":"panic occurred while running scan, see debug logs","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/remote/remote.go","lineNumber":68,"sourceCode":"}\n\nfunc (r *Library) addError(k string, err error) {\n\tr.m.Lock()\n\tdefer r.m.Unlock()\n\tr.errors[k] = err\n}\n\nfunc (r *Library) Scan(n *number.Number, opts ScannerOptions) (map[string]interface{}, map[string]error) {\n\tvar wg sync.WaitGroup\n\n\tfor _, s := range r.scanners {\n\t\twg.Add(1)\n\t\tgo func(s Scanner) {\n\t\t\tdefer wg.Done()\n\t\t\tdefer func() {\n\t\t\t\tif err := recover(); err != nil {\n\t\t\t\t\tlogrus.WithField(\"scanner\", s.Name()).WithField(\"error\", err).Debug(\"Scanner panicked\")\n\t\t\t\t\tr.addError(s.Name(), errors.New(\"panic occurred while running scan, see debug logs\"))\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tif err := s.DryRun(*n, opts); err != nil {\n\t\t\t\tlogrus.\n\t\t\t\t\tWithField(\"scanner\", s.Name()).\n\t\t\t\t\tWithField(\"reason\", err.Error()).\n\t\t\t\t\tDebug(\"Scanner was ignored because it should not run\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdata, err := s.Run(*n, opts)\n\t\t\tif err != nil {\n\t\t\t\tr.addError(s.Name(), err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif data != nil {\n\t\t\t\tr.addResult(s.Name(), data)","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/sundowndev/phoneinfoga/blob/55807b05b753dab7bc6fe67403ca385668dda179/lib/remote/remote.go#L50-L86","documentation":"remote.go wraps each scanner in a recover() guard inside its goroutine; if a scanner panics (nil dereference, index out of range, etc.), the panic is converted into the collected error 'panic occurred while running scan, see debug logs' attributed to that scanner. The real panic value and stack details are only logged at debug level.","triggerScenarios":"Any scanner's DryRun or Run panics at runtime — e.g. nil pointer inside a supplier client, unexpected response shape causing an index/range panic, or a nil interface in a third-party dependency.","commonSituations":"Hitting an upstream API that returns an unexpected payload the scanner code assumes is well-formed, a bug in a custom scanner, or a dependency regression after an upgrade.","solutions":["Re-run with debug logging enabled (--debug / logrus debug level) to see which scanner panicked and the panic value","Update the library and its suppliers to the latest version — the panic may already be fixed","Isolate by disabling scanners one at a time to find the faulty one","If it is a custom/new scanner, add nil checks on API responses before use","Report the panic (with the debug log) to the maintainers"],"exampleFix":"// before\nscan --number +14155552671   # 'panic occurred while running scan'\n// after\nscan --number +14155552671 --debug   # reveals e.g. scanner=ovh, error=\"runtime error: index out of range\"","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// the library already recovers; treat this like a scanner failure and inspect debug logs\nerrs := result.Errors()\nfor _, e := range errs {\n    if strings.Contains(e.Error(), \"panic occurred while running scan\") {\n        log.Warnf(\"scanner %s panicked; rerun with debug logging\", e.Scanner)\n    }\n}","preventionTips":["Run with debug logging to capture the panic value and scanner name","Keep the library updated so known panics are patched","Validate phone-number input up front to avoid unexpected parser states","Isolate custom scanners with tests covering malformed API responses"],"tags":["panic","concurrency","goroutine","recovery"],"backgroundTag":"goroutine-panic-recovered","analyzedSha":"55807b05b753dab7bc6fe67403ca385668dda179","analyzedAt":"2026-09-03T13:37:27.908Z","contentChangedAt":"2026-09-03T13:37:27.908Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}