# Debug Session: no-website-phone-bug
- **Status**: [OPEN]
- **Issue**: Google Maps extraction for the `no_website` filter still stores fake phone values like `4.6(796)` and sometimes stores rating/review text in `address`.
- **Debug Server**: http://127.0.0.1:7777/event
- **Log File**: .dbg/trae-debug-log-no-website-phone-bug.ndjson

## Reproduction Steps
1. Open Google Maps search results.
2. Choose the `No Website` filter in the extension popup.
3. Set `Max Leads` to 15.
4. Start extraction and export JSON.
5. Inspect entries with missing or incorrect phone/address fields.

## Hypotheses & Verification
| ID | Hypothesis | Likelihood | Effort | Evidence |
|----|------------|------------|--------|----------|
| A | Detail-panel extraction sometimes fails to open or load before reading fields, so fallback card parsing is used. | High | Medium | Confirmed by exported records that contain fallback-shaped values and by `Le Sud` being exported as `hasWebsite: false` despite a live website field. |
| B | Fallback phone parsing still treats `rating + reviews` text as a phone because punctuation is stripped into a numeric-looking token. | High | Low | Confirmed by exported `phone: "4.6(796)"` and validator test showing old pattern was too permissive. |
| C | Returning to results too early or on the wrong view causes subsequent cards to be matched incorrectly. | Medium | Medium | Confirmed by live detail-page inspection: old broad selectors matched non-result elements while still on a place page. |
| D | `No Website` businesses often omit website but still expose phone only in the details panel, so card-only fallback is insufficient. | High | Low | Confirmed by live Maps pages where detail selectors expose business fields more reliably than result cards. |
| E | Some result cards do not have a valid stable key after navigation, so the scraper resumes from a stale or mismatched card. | Medium | Medium | Partially mitigated by stricter result-card detection; no separate evidence yet. |
| F | After reloading the extension, an old content-script context remains on the page and throws when calling `chrome.runtime.sendMessage` or `chrome.storage.local.set`. | High | Low | Confirmed by stack traces landing on runtime messaging lines in the latest file. |

## Log Evidence
- Exported JSON evidence:
  - `Le Sud Mediterranean Kitchen` had `phone: "4.6(796)"` and `website: ""`.
  - `Quartino Ristorante` had `address: "4.7(15,396)"`.
- Live Google Maps evidence:
  - `Le Sud Mediterranean Kitchen` detail page shows `Website: lesudchicago.com`.
  - Detail-page selector check with tightened card selectors returns `0` results, proving the scraper can now distinguish place view from results view.
- Validation evidence:
  - `isLikelyPhone("4.6(796)") === false`
  - `isLikelyPhone("(312) 967-6060") === true`
  - `isLikelyPhone("+1 773-645-1400") === true`
  - Ranchi stack trace maps to `sendStatus()` / runtime messaging in the latest file.

## Verification Conclusion
- Pre-fix:
  - Some `no_website` exports contained businesses with real websites.
  - Some `phone` and `address` fields were populated with rating/review strings.
- Fix:
  - Restricted listing detection to actual result cards in the search feed.
  - Made return-to-results detection require search-view state.
  - Tightened phone validation to reject rating/review tokens.
  - Added guarded runtime messaging/storage wrappers so stale content-script contexts do not crash the scraper.
- Post-fix:
  - Static validation passes.
  - Live selector validation confirms detail pages no longer masquerade as results pages.
  - Awaiting user retest with a freshly reloaded extension and new export.
