sickn33/agentic-awesome-skills · error · Error
Must be object
Error message
Must be object
What it means
First guard of the multi-check validateUser example in the fp-pragmatic skill (skills/fp-pragmatic/SKILL.md:465). Thrown when the raw input is falsy or not an object: the shape check that must pass before any field can be safely read. The doc replaces this throw-on-first-error style with an error-accumulating Either version.
Source
Thrown at skills/fp-pragmatic/SKILL.md:465
O.flatMap(m => O.fromNullable(m.email))
)
// Use it
pipe(
getManagerEmail(employee),
O.fold(
() => sendToDefault(),
(email) => sendTo(email)
)
)
```
### Validation with Multiple Checks
```typescript
// Before: Throws on first error
function validateUser(data: unknown): User {
if (!data || typeof data !== 'object') throw new Error('Must be object')
const obj = data as Record<string, unknown>
if (typeof obj.email !== 'string') throw new Error('Email required')
if (!obj.email.includes('@')) throw new Error('Invalid email')
if (typeof obj.age !== 'number') throw new Error('Age required')
if (obj.age < 0) throw new Error('Age must be positive')
return obj as User
}
// After: Returns first error, type-safe
const validateUser = (data: unknown): E.Either<string, User> =>
pipe(
E.Do,
E.bind('obj', () =>
typeof data === 'object' && data !== null
? E.right(data as Record<string, unknown>)
: E.left('Must be object')
),
E.bind('email', ({ obj }) =>View on GitHub (pinned to 58d857988f)
Solutions
- Parse and validate the payload shape at the boundary with a schema library (zod, io-ts, valibot) before it reaches domain code
- Use the doc AFTER pattern: return Either with accumulated errors instead of throwing on the first failed check
- Reject non-object bodies early in the HTTP layer with a 400 and a clear message
Example fix
// before
if (!data || typeof data !== 'object') throw new Error('Must be object')
// after
const isRecord = (u: unknown): u is Record<string, unknown> =>
typeof u === 'object' && u !== null && !Array.isArray(u)
if (!isRecord(data)) return E.left(['Must be object']) Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof data !== 'object' || data === null || Array.isArray(data)) {
return badRequest('body must be a JSON object')
} Type guard
const isRecord = (u: unknown): u is Record<string, unknown> => typeof u === 'object' && u !== null && !Array.isArray(u)
Prevention
- Validate payload shape at the HTTP boundary before domain code
- Use zod/io-ts schemas for unknown input
- Accumulate validation errors instead of throwing on the first
When it happens
Trigger: Calling validateUser with null, undefined, a string, a number, or an array: anything where typeof data is not object or data is null.
Common situations: JSON.parse of an empty or malformed request body producing null; query-string params arriving as strings; arrays passing the typeof check but failing later field checks; API consumers sending scalars where objects are expected.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid range "${t}" in ${fieldDef.name}
- Value ${v} out of range for ${fieldDef.name} (${fieldDef.min
- Range ${lo}-${hi} out of bounds for ${fieldDef.name} (${fiel
- Expected 5 fields (got ${parts.length}). Format: minute hour
- ID required
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/4eb3a9db73945a79.
Report an issue: GitHub.