{"record":{"id":"53f0d0b5450d622f","repo":"sickn33/agentic-awesome-skills","slug":"age-required","errorCode":null,"errorMessage":"Age required","messagePattern":"Age required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"skills/fp-pragmatic/SKILL.md","lineNumber":469,"sourceCode":"pipe(\n  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    ),","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/sickn33/agentic-awesome-skills/blob/58d857988fcfac6986206bca2b2fe223aa437e4b/skills/fp-pragmatic/SKILL.md#L451-L487","documentation":"This error is thrown by the 'Before' (throw-based) validation example in the fp-pragmatic skill. It fires when the input object exists but its `age` field is not a number (missing, string, null, etc.). The skill shows it as the anti-pattern to replace with an fp-ts Either-based validator that returns the first error as a value.","triggerScenarios":"Calling validateUser(data) where data is an object with a valid email containing '@' but data.age is undefined, null, a string like '30', or NaN.","commonSituations":"Form submissions where age input arrives as a string from HTML forms or query strings; JSON payloads with optional fields omitted; API consumers sending partially-filled DTOs.","solutions":["Coerce or parse the age field (Number(obj.age)) before validation if the source is a form or query param","Add a schema check (zod/io-ts) at the API boundary so age is guaranteed numeric before it reaches validateUser","Refactor to the skill's Either version so the error is returned as a value instead of thrown"],"exampleFix":"// before\nif (typeof obj.age !== 'number') throw new Error('Age required')\n\n// after (Either-based, first error as value)\nconst validateUser = (data: unknown): E.Either<string, User> =>\n  pipe(\n    // ...checks returning E.left('Age required') when age is not a number\n  )","handlingStrategy":"type-guard","validationCode":"const hasNumberAge = (x: unknown): boolean =>\n  typeof x === 'object' && x !== null && typeof (x as any).age === 'number'","typeGuard":"const hasAge = (x: unknown): x is { age: number } =>\n  typeof x === 'object' && x !== null && typeof (x as Record<string, unknown>).age === 'number'","tryCatchPattern":null,"preventionTips":["Parse/convert numeric form inputs before passing to validators","Validate payloads with a schema at the API boundary"],"tags":["validation","typescript","fp-ts","runtime-type-check"],"backgroundTag":"schema-validation-failed","analyzedSha":"58d857988fcfac6986206bca2b2fe223aa437e4b","analyzedAt":"2026-08-26T11:55:59.350Z","schemaVersion":2},"datasetVersion":"2026-08-26T14:46:13.012Z"}