{"record":{"id":"eac1b8f2ed551ffd","repo":"paperclipai/paperclip","slug":"name-must-be-a-positive-number","errorCode":null,"errorMessage":"${name} must be a positive number.","messagePattern":"(.+?) must be a positive number\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugins/plugin-llm-wiki/src/wiki/core.ts","lineNumber":488,"sourceCode":"    space,\n    profile,\n    purpose,\n    requireEnabledProfile: options.requireEnabledProfile,\n  });\n  if (!decision.allowed) throw new Error(decision.message);\n  return decision.space;\n}\n\nfunction assertPaperclipSourceScopePayload(input: { projectId?: string | null; rootIssueId?: string | null }) {\n  if (input.projectId && input.rootIssueId) {\n    throw new Error(\"Paperclip source scope must specify either projectId or rootIssueId, not both.\");\n  }\n}\n\nfunction assertRequestedCharacterLimit(name: string, value: unknown, max: number) {\n  if (value == null) return;\n  if (typeof value !== \"number\" || !Number.isFinite(value) || value < 1) {\n    throw new Error(`${name} must be a positive number.`);\n  }\n  if (Math.floor(value) > max) {\n    throw new Error(`${name} exceeds the hard Paperclip ingestion cap of ${max} characters.`);\n  }\n}\n\nfunction stableSpaceId(input: { companyId: string; wikiId: string; slug: string }): string {\n  const hex = createHash(\"md5\")\n    .update(`${input.companyId}:${input.wikiId}:${input.slug}`)\n    .digest(\"hex\");\n  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-8${hex.slice(17, 20)}-${hex.slice(20, 32)}`;\n}\n\nfunction normalizeLimit(value: unknown, fallback: number, max: number): number {\n  if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n  return Math.max(1, Math.min(max, Math.floor(value)));\n}\n","sourceCodeStart":470,"sourceCodeEnd":506,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/plugins/plugin-llm-wiki/src/wiki/core.ts#L470-L506","documentation":"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).","triggerScenarios":"Passing limit: 0, a negative number, NaN, Infinity, a numeric string (\"100\"), or an object. Passing a value from untyped config without coercion.","commonSituations":"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'.","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."],"exampleFix":"// before\nassertRequestedCharacterLimit(\"maxCharacters\", \"100\", 1000); // throws — string not number\nassertRequestedCharacterLimit(\"maxCharacters\", 0, 1000); // throws — < 1\n// after\nassertRequestedCharacterLimit(\"maxCharacters\", 100, 1000);\n// or omit:\nassertRequestedCharacterLimit(\"maxCharacters\", null, 1000);","handlingStrategy":"type-guard","validationCode":"function assertLimit(name: string, value: unknown, max: number) {\n  if (value == null) return;\n  if (typeof value !== \"number\" || !Number.isFinite(value) || value < 1) {\n    throw new Error(`${name} must be a positive number.`);\n  }\n}","typeGuard":"function isPositiveFiniteNumber(v: unknown): v is number {\n  return typeof v === \"number\" && Number.isFinite(v) && v >= 1;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["llm-wiki","validation","numeric","paperclip"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}