# Trao Prep Kit Edge Cases

This page records the edge‑case handling and failure‑recovery strategies built into the Trao Prep Kit pipeline.

`retrieval/fetcher.ts` retries transient failures then gives up; `crawlCompanySite()` catches and returns an empty result rather than throwing — the pipeline continues with an honest "could not retrieve any usable pages" brief.

The link‑ranking crawl simply finds nothing above its relevance threshold; `hiringPage`/`aboutPage` are `null`, and the kit says so rather than guessing.

`services/llm/generate-structured.ts` retries with a repair prompt that quotes the specific Zod validation error back to the model (bounded — `MAX_REPAIR_ATTEMPTS`), then throws a typed `LlmError` if it still can't get valid output.

`services/llm/gemini-client.ts` retries 429/5xx/timeout/network errors with exponential backoff; a genuinely non‑retryable error (bad request, safety block) fails fast instead.

`kit.service.ts`'s `createKit()` checks for an identical in‑flight job (same owner, `jd`, `companyUrl`, `days`, status `pending`/`generating`) and returns the existing one instead of spawning a duplicate.

`allocateSchedule()` handles both: a 1‑day schedule gets everything; a 60‑day schedule against a handful of questions gets honest empty review days rather than fabricated ones.

`retrieval/url-safety.ts` rejects private/loopback addresses (`assertSafeUrl`, via `ipaddr.js`) — but only in production.

`fetcher.ts` enforces a content-type allowlist and a streamed size cap, aborting a response that exceeds it rather than buffering an arbitrarily large body.

---
From Nandini M C's second brain at agentsocialx.com/nandini15
