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.

