## TL;DR
HubSpot's search index lags behind writes, so a contact created seconds ago can be invisible to search while still existing. When create returns 409 CONTACT_EXISTS, trust the 409, not the search: fetch the existing contact by email and update it instead of creating.

```text
hubspot 409 CONTACT_EXISTS on agent create  -  but the search before it returned nothing because of index lag
```

## Steps
1. On any 409 CONTACT_EXISTS, read the error body for the existing contact's id. HubSpot usually includes it.
   Expected: you have the existing contact id without another search.
2. If no id is in the error, look the contact up by email through the CRM read path (get-by-email), not the search path, and wait for it.
   Expected: the contact record comes back with its properties.
3. Change the agent's flow from create-then-fail to upsert: search first, create on miss, and on 409 fetch the existing record and apply the intended updates to it.
   Expected: the agent never drops data on a 409 again.
4. Add a short delay-and-retry around the pre-create search for records the same run just created, so the index has time to catch up.
   Expected: fewer false "not found" results within a single run.
5. Log every 409 as an update event with the contact id, so downstream steps (sequence enrollment, task creation) target the right record.
   Expected: the pipeline treats the 409 as a normal branch, not an error.

## Use this when
- The agent searches, finds nothing, creates, and gets 409 CONTACT_EXISTS.
- Two near-simultaneous runs create the same contact.
- The contact was created minutes ago by the same agent.

## Not for this skill when
- The search correctly finds the contact and the agent creates anyway (a logic bug, not index lag).
- The error is a validation error or a permission error.
- Duplicates come from bad dedupe keys rather than timing.

## Variant phrasings
- "hubspot create says contact exists but search found nothing"
- "CONTACT_EXISTS right after a failed search"
- "hubspot search index lag on contact create"

## Why it happens
HubSpot search runs on an eventually consistent index. Writes land in the contact store immediately but can take seconds to minutes to appear in search results. A create-then-search or search-then-create flow inside one fast agent run can therefore see a contact as absent and then collide with it on create.

## Edge cases
- The lag window varies; a fixed sleep is a heuristic, not a guarantee. The 409 branch is the real fix.
- If the error body lacks the id and get-by-email also misses, wait and retry the lookup before giving up.
- Merging properties on update can overwrite newer values. Update only the fields the run intended to set.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_EAqo0KJ9g6A4iOunZG34mQ
