{"record":{"id":"1cb66d4a324aadfb","repo":"paperclipai/paperclip","slug":"queue-maxsize-must-be-a-positive-safe-integer","errorCode":null,"errorMessage":"Queue maxSize must be a positive safe integer","messagePattern":"Queue maxSize must be a positive safe integer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/services/chat-sdk-state.ts","lineNumber":346,"sourceCode":"    throw this.casExhausted(\"append list value\");\n  }\n\n  async getList<T = unknown>(key: string): Promise<T[]> {\n    const current = await this.readLive(\"list\", key);\n    if (!current) return [];\n    if (!Array.isArray(current.value))\n      throw new Error(\"Invalid Chat SDK list state\");\n    return current.value as T[];\n  }\n\n  async enqueue(\n    threadId: string,\n    entry: QueueEntry,\n    maxSize: number,\n  ): Promise<number> {\n    this.ensureConnected();\n    if (!(Number.isSafeInteger(maxSize) && maxSize > 0)) {\n      throw new Error(\"Queue maxSize must be a positive safe integer\");\n    }\n    const key = storageKey(\"queue\", threadId);\n    for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt += 1) {\n      const record = await this.persistence.read(this.scope, key);\n      const prior =\n        record && !this.isExpired(record)\n          ? decodeEnvelope(record, \"queue\")\n          : [];\n      if (!Array.isArray(prior))\n        throw new Error(\"Invalid Chat SDK queue state\");\n      const now = this.now().getTime();\n      const live = (prior as QueueEntry[]).filter(\n        (item) => item.expiresAt > now,\n      );\n      const next = [...live, entry].slice(-maxSize);\n      const expiresAt = new Date(\n        Math.max(...next.map((item) => item.expiresAt)),\n      );","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/services/chat-sdk-state.ts#L328-L364","documentation":"enqueue validates maxSize (the queue capacity for a thread) must be a positive safe integer before reading and CAS-updating the stored queue. Zero, negatives, non-integers, and NaN/Infinity cannot form a valid bounded queue and are rejected.","triggerScenarios":"Calling enqueue(threadId, entry, 0), a negative size, a fractional size, or a size sourced from unvalidated config/env; passing NaN after a failed Number() parse.","commonSituations":"Queue capacity from an env var parsed without validation; division producing fractional values; a misconfigured default of 0 interpreted as 'unlimited' by the caller but rejected by the API.","solutions":["Validate first: Number.isSafeInteger(maxSize) && maxSize > 0","Coerce config with Math.round(Number(raw)) and re-validate","Omit/throw on unset capacity instead of passing 0"],"exampleFix":"// before\nawait queue.enqueue(threadId, entry, Number(env.QUEUE_MAX));\n// after\nconst maxSize = Math.round(Number(env.QUEUE_MAX));\nif (!(Number.isSafeInteger(maxSize) && maxSize > 0)) throw new Error(`QUEUE_MAX invalid: ${env.QUEUE_MAX}`);\nawait queue.enqueue(threadId, entry, maxSize);","handlingStrategy":"validation","validationCode":"if (!(Number.isSafeInteger(maxSize) && maxSize > 0)) throw new Error('maxSize must be a positive safe integer');","typeGuard":"function isPositiveSafeInt(v: unknown): v is number { return typeof v === 'number' && Number.isSafeInteger(v) && v > 0; }","tryCatchPattern":"try { await queue.enqueue(threadId, entry, maxSize); } catch (err) { if (/Queue maxSize must be a positive safe integer/.test((err as Error).message)) { maxSize = DEFAULT_QUEUE_MAX; return queue.enqueue(threadId, entry, maxSize); } throw err; }","preventionTips":["Define queue capacity constants in code instead of ad-hoc parsing","Validate numeric env/config at startup, fail fast","Use Math.round(Number(x)) before integer-typed options"],"tags":["validation","queue","argument-error"],"backgroundTag":"invalid-argument-value","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}