{"record":{"id":"0e87f27908e29d28","repo":"sickn33/agentic-awesome-skills","slug":"age-must-be-positive","errorCode":null,"errorMessage":"Age must be positive","messagePattern":"Age must be positive","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"skills/fp-pragmatic/SKILL.md","lineNumber":470,"sourceCode":"  getManagerEmail(employee),\n  O.fold(\n    () => sendToDefault(),\n    (email) => sendTo(email)\n  )\n)\n```\n\n### Validation with Multiple Checks\n\n```typescript\n// Before: Throws on first error\nfunction validateUser(data: unknown): User {\n  if (!data || typeof data !== 'object') throw new Error('Must be object')\n  const obj = data as Record<string, unknown>\n  if (typeof obj.email !== 'string') throw new Error('Email required')\n  if (!obj.email.includes('@')) throw new Error('Invalid email')\n  if (typeof obj.age !== 'number') throw new Error('Age required')\n  if (obj.age < 0) throw new Error('Age must be positive')\n  return obj as User\n}\n\n// After: Returns first error, type-safe\nconst validateUser = (data: unknown): E.Either<string, User> =>\n  pipe(\n    E.Do,\n    E.bind('obj', () =>\n      typeof data === 'object' && data !== null\n        ? E.right(data as Record<string, unknown>)\n        : E.left('Must be object')\n    ),\n    E.bind('email', ({ obj }) =>\n      typeof obj.email === 'string' && obj.email.includes('@')\n        ? E.right(obj.email)\n        : E.left('Valid email required')\n    ),\n    E.bind('age', ({ obj }) =>","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/sickn33/agentic-awesome-skills/blob/58d857988fcfac6986206bca2b2fe223aa437e4b/skills/fp-pragmatic/SKILL.md#L452-L488","documentation":"Thrown by the throw-based validateUser example in fp-pragmatic when `age` is a number but is negative. It represents a range/semantic check layered after the type check, and the skill contrasts it with an Either pipeline that surfaces the same failure without exceptions.","triggerScenarios":"Calling validateUser with an object whose email is valid and age is a negative number, e.g. { email: 'a@b.c', age: -1 }.","commonSituations":"Test fixtures with sentinel values like -1; arithmetic that computes age from dates with an inverted subtraction; free-text numeric fields accepting minus signs.","solutions":["Clamp or reject negative values at the input layer (min='0' on numeric inputs)","Validate with a boundary-aware schema (zod .nonnegative() / io-ts brand) before business logic","Return the error via Either/Result instead of throwing, as the skill's 'After' version does"],"exampleFix":"// before\nif (obj.age < 0) throw new Error('Age must be positive')\n\n// after\nconst ageCheck = (obj: Record<string, unknown>) =>\n  typeof obj.age === 'number' && obj.age >= 0\n    ? E.right(obj as User)\n    : E.left('Age must be positive')","handlingStrategy":"validation","validationCode":"const isValidAge = (a: unknown) => typeof a === 'number' && Number.isFinite(a) && a >= 0","typeGuard":"const hasNonNegativeAge = (x: unknown): x is { age: number } =>\n  typeof x === 'object' && x !== null && typeof (x as any).age === 'number' && (x as any).age >= 0","tryCatchPattern":null,"preventionTips":["Use min=0 constraints on numeric inputs and schema fields","Compute age from dates with checked ordering"],"tags":["validation","range-check","typescript"],"backgroundTag":"schema-validation-failed","analyzedSha":"58d857988fcfac6986206bca2b2fe223aa437e4b","analyzedAt":"2026-08-26T11:55:59.350Z","schemaVersion":2},"datasetVersion":"2026-08-26T14:46:13.012Z"}