tinyhumansai/openhuman · error
agentTeamApi: ${label} must be a positive integer
Error message
agentTeamApi: ${label} must be a positive integer What it means
Client-side pre-flight validation in agentTeamApi. The helper assertPositiveInt rejects any explicitly-supplied pagination value that is not an integer greater than zero, before the JSON-RPC call to the core is made. It exists so bad limit/offset values fail fast in the renderer instead of surfacing as confusing core-side errors.
Source
Thrown at app/src/services/api/agentTeamApi.ts:160
interface RawRunEvent {
runId: string;
sequence: number;
eventType: string;
payload: unknown;
timestamp: string;
}
/** Optional filters for {@link agentTeamApi.list}. Mirrors `AgentTeamListRequest`. */
interface AgentTeamListParams {
parentThreadId?: string;
status?: AgentTeamStatus;
limit?: number;
offset?: number;
}
function assertPositiveInt(value: number | undefined, label: string): void {
if (value !== undefined && (!Number.isInteger(value) || value <= 0)) {
throw new Error(`agentTeamApi: ${label} must be a positive integer`);
}
}
/** Coerce a raw run-event payload into a typed message payload, defensively. */
function readMessagePayload(payload: unknown): TeamMessagePayload {
const p = (payload ?? {}) as Record<string, unknown>;
return {
from: typeof p.from === 'string' ? p.from : '',
to: typeof p.to === 'string' ? p.to : null,
content: typeof p.content === 'string' ? p.content : '',
visibility: typeof p.visibility === 'string' ? p.visibility : 'team',
};
}
export const agentTeamApi = {
/**
* List team headers, newest first. Filters are optional; `parentThreadId`
* scopes to one conversation, `status` to active/closed.View on GitHub (pinned to a221052e0d)
Solutions
- Fix the caller to pass undefined instead of 0 when no cap is intended — undefined skips the check entirely
- Clamp computed pagination values before calling: limit = Math.max(1, Math.floor(limit))
- If 0 legitimately means 'no limit' in your UI, translate it: params.limit || undefined
- Trace where the non-integer originates (query param parsing, division) and round it
Example fix
// before
const teams = await agentTeamApi.list({ limit: pageEnd - pageStart }); // 0 on empty page
// after
const teams = await agentTeamApi.list({ limit: Math.max(1, pageEnd - pageStart) });
// or omit entirely when there is nothing to page:
const teams = await agentTeamApi.list(pageEnd - pageStart > 0 ? { limit: pageEnd - pageStart } : {}); Defensive patterns
Strategy: validation
Validate before calling
function safePage(v: number | undefined): number | undefined {
if (v === undefined) return undefined;
const n = Math.floor(v);
return Number.isFinite(n) && n > 0 ? n : undefined;
}
// before the call:
const params = { status, limit: safePage(limit), offset: safePage(offset) };
if (limit !== undefined && params.limit === undefined) throw new Error('bad limit'); Type guard
const isPositiveInt = (v: unknown): v is number => typeof v === 'number' && Number.isInteger(v) && v > 0;
Try / catch
try { await agentTeamApi.list({ limit }); }
catch (e) { if (String(e.message).includes('positive integer')) { limit = undefined; retryWithoutCap(); } else throw e; } Prevention
- Treat 0/undefined as the same 'no cap' at your call boundary and normalize once
- Never pass raw parsed query-string numbers straight into pagination params
- Centralize page-size computation in one helper so the clamp lives in one place
When it happens
Trigger: Calling agentTeamApi.list({ limit: 0 }), list({ limit: -5 }), list({ offset: 2.5 }), or list({ limit: NaN }) — i.e. any call where limit/offset is defined but fails Number.isInteger(value) || value <= 0. Note assertPositiveInt is also reused by listMessages (line 216) with the label 'limit'.
Common situations: UI pagination math that computes limit as pageEnd - pageStart and yields 0 on an empty page; passing a float from a slider or a parsed query-string param (e.g. Number('2.5')); defaults accidentally set to 0; NaN propagation from Number(undefined).
Related errors
- agentTeamApi.get: teamId is required
- agentTeamApi.listMessages: teamId is required
- agentTeamApi.completeTask: teamId, taskId and memberId are r
- agentTeamApi.shutdownMember: teamId and memberId are require
- agentTeamApi.messageMember: teamId is required
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/2a368c2dc07510ea.
Report an issue: GitHub.