paperclipai/paperclip · error · Error
${name} must be a positive number.
Error message
${name} must be a positive number. What it means
Thrown by assertRequestedCharacterLimit() when a character-limit value is provided (non-null) but is not a finite number, or is less than 1. Limits must be positive integers; zero, negatives, NaN, Infinity, and non-number types are rejected. A null/undefined value is allowed and returns early (the field is optional).
Source
Thrown at packages/plugins/plugin-llm-wiki/src/wiki/core.ts:488
space,
profile,
purpose,
requireEnabledProfile: options.requireEnabledProfile,
});
if (!decision.allowed) throw new Error(decision.message);
return decision.space;
}
function assertPaperclipSourceScopePayload(input: { projectId?: string | null; rootIssueId?: string | null }) {
if (input.projectId && input.rootIssueId) {
throw new Error("Paperclip source scope must specify either projectId or rootIssueId, not both.");
}
}
function assertRequestedCharacterLimit(name: string, value: unknown, max: number) {
if (value == null) return;
if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
throw new Error(`${name} must be a positive number.`);
}
if (Math.floor(value) > max) {
throw new Error(`${name} exceeds the hard Paperclip ingestion cap of ${max} characters.`);
}
}
function stableSpaceId(input: { companyId: string; wikiId: string; slug: string }): string {
const hex = createHash("md5")
.update(`${input.companyId}:${input.wikiId}:${input.slug}`)
.digest("hex");
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-8${hex.slice(17, 20)}-${hex.slice(20, 32)}`;
}
function normalizeLimit(value: unknown, fallback: number, max: number): number {
if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
return Math.max(1, Math.min(max, Math.floor(value)));
}
View on GitHub (pinned to 67001ec6eb)
Solutions
- Pass a positive finite number (>= 1), or pass null/undefined to omit the limit.
- If accepting user input, coerce with Number() and validate Number.isFinite && >= 1 before calling.
- Treat empty input as null (omit) rather than 0 in the form layer.
Example fix
// before
assertRequestedCharacterLimit("maxCharacters", "100", 1000); // throws — string not number
assertRequestedCharacterLimit("maxCharacters", 0, 1000); // throws — < 1
// after
assertRequestedCharacterLimit("maxCharacters", 100, 1000);
// or omit:
assertRequestedCharacterLimit("maxCharacters", null, 1000); Defensive patterns
Strategy: type-guard
Validate before calling
function assertLimit(name: string, value: unknown, max: number) {
if (value == null) return;
if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
throw new Error(`${name} must be a positive number.`);
}
} Type guard
function isPositiveFiniteNumber(v: unknown): v is number {
return typeof v === "number" && Number.isFinite(v) && v >= 1;
} Prevention
- Coerce user input with Number() and validate before passing.
- Represent 'no limit' as null/undefined, not 0.
- Add input[type=number] min=1 and validate at the form layer.
When it happens
Trigger: Passing limit: 0, a negative number, NaN, Infinity, a numeric string ("100"), or an object. Passing a value from untyped config without coercion.
Common situations: UI form defaulting an empty input to 0 instead of null. Config value parsed from a query string as a string instead of a number. Off-by-one where 0 was meant to mean 'unlimited'.
Related errors
- ${name} exceeds the hard Paperclip ingestion cap of ${max} c
- Paperclip source scope must specify either projectId or root
- Paperclip ingestion profile must include at least one source
- Paperclip skills must be directories.
- Invalid SSH environment variable key: ${key}
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/eac1b8f2ed551ffd.
Report an issue: GitHub.