tinyhumansai/openhuman · error · ValidationError
Invalid ${paramName}: ${String(value)}. Must be a positive i
Error message
Invalid ${paramName}: ${String(value)}. Must be a positive integer. What it means
The fallback branch of validatePositiveInt(): the value is neither number nor string (boolean, null, object, array, undefined passed where not allowed), so it throws ValidationError 'Invalid <param>: <String(value)>. Must be a positive integer.' — a wrong-type failure rather than a bad-value one.
Source
Thrown at app/src/lib/mcp/validation.ts:91
* Validate a positive integer parameter (e.g. message IDs)
*/
export function validatePositiveInt(value: unknown, paramName: string): number {
if (typeof value === 'number') {
if (!Number.isInteger(value) || value <= 0) {
throw new ValidationError(`Invalid ${paramName}: ${value}. Must be a positive integer.`);
}
return value;
}
if (typeof value === 'string') {
const intValue = Number.parseInt(value, 10);
if (Number.isNaN(intValue) || intValue <= 0) {
throw new ValidationError(`Invalid ${paramName}: '${value}'. Must be a positive integer.`);
}
return intValue;
}
throw new ValidationError(`Invalid ${paramName}: ${String(value)}. Must be a positive integer.`);
}
/**
* Validate optional ID (can be undefined)
*/
export function validateOptionalId(value: unknown, paramName: string): number | string | undefined {
if (value === undefined || value === null) {
return undefined;
}
return validateId(value, paramName);
}
View on GitHub (pinned to 7491200858)
Solutions
- Check the value's type before the call: require typeof number (integer > 0) or numeric string.
- Fix argument construction — the message shows the actual value, making key-mixups visible.
- Add shared param types (TS interfaces) for tool payloads so the compiler catches swapped/missing fields.
- Convert booleans/objects upstream instead of relying on the validator's error at runtime.
Example fix
// before
await tool({ message_id: payload.id ?? null });
// after
const id = payload.id;
if (typeof id !== 'number' || !Number.isInteger(id) || id < 1) {
throw new TypeError('payload.id must be a positive integer');
}
await tool({ message_id: id }); Defensive patterns
Strategy: type-guard
Validate before calling
function asPositiveInt(v: unknown): number | undefined {
if (typeof v === 'number' && Number.isInteger(v) && v > 0) return v;
const m = typeof v === 'string' ? /^\d+$/.exec(v) : null;
return m && Number(m[0]) > 0 ? Number(m[0]) : undefined;
}
if (asPositiveInt(payload.id) === undefined) throw new TypeError('id must be a positive integer'); Type guard
function isPositiveIntLike(v: unknown): v is number | string {
if (typeof v === 'number') return Number.isInteger(v) && v > 0;
if (typeof v === 'string') return /^\d+$/.test(v) && Number(v) > 0;
return false;
} Try / catch
try {
validatePositiveInt(value, paramName);
} catch (err) {
if (err instanceof ValidationError) {
// wrong type (null/bool/object) — fix the caller's payload construction
logPayloadShape(value);
return badRequest(err.message);
}
throw err;
} Prevention
- Type tool params with shared interfaces; never forward untyped JSON straight into MCP calls.
- Destructure explicitly rather than passing whole objects into ID fields.
- Let TypeScript strict null checks surface null/undefined before runtime.
When it happens
Trigger: Passing null, true/false, an object ({id: 3} instead of 3), or an array ([3]) as the parameter. Typical when callers forward unvalidated JSON payloads or destructure with the wrong key.
Common situations: Tool params deserialized from untyped JSON where a field is sometimes an object; boolean flags accidentally passed in the ID slot due to argument-order mistakes; nulls from optional chaining defaults (value ?? null).
Related errors
- Invalid ${paramName}: ${value}. Must be a positive integer.
- Invalid ${paramName}: '${value}'. Must be a positive integer
- Recovery phrase is required.
- "{key}" is required
- mascot manifest: missing mascots array
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/8ecbf149e596a71f.
Report an issue: GitHub.