{"record":{"id":"c61789d87ecd7501","repo":"chatboxai/chatbox","slug":"too-many-file-ids-requested-max-100","errorCode":null,"errorMessage":"Too many file IDs requested (max 100)","messagePattern":"Too many file IDs requested \\(max 100\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/knowledge-base/ipc-handlers.ts","lineNumber":380,"sourceCode":"        scope.setExtra('limit', limit)\n        sentry.captureException(error)\n      })\n      throw error\n    }\n  })\n\n  ipcMain.handle('kb:file:get-metas', async (_event, kbId: number, fileIds: number[]) => {\n    try {\n      log.debug(`ipcMain: kb:file:get-metas, kbId=${kbId}, fileIds=${fileIds.join(',')}`)\n\n      if (!kbId || kbId <= 0) {\n        throw new Error('Invalid knowledge base ID')\n      }\n      if (!fileIds || fileIds.length === 0) {\n        return []\n      }\n      if (fileIds.length > 100) {\n        throw new Error('Too many file IDs requested (max 100)')\n      }\n\n      const db = getDatabase()\n      const placeholders = fileIds.map(() => '?').join(',')\n      const sql = `SELECT id, kb_id, filename, mime_type, file_size, chunk_count, total_chunks, status, created_at FROM kb_file WHERE kb_id = ? AND id IN (${placeholders})`\n      const rs = await db.execute({\n        sql,\n        args: [kbId, ...fileIds],\n      })\n      return rs.rows.map((row) => ({\n        id: row.id,\n        kbId: row.kb_id,\n        filename: row.filename,\n        mimeType: row.mime_type,\n        fileSize: row.file_size || 0,\n        chunkCount: row.chunk_count || 0,\n        totalChunks: row.total_chunks || 0,\n        status: row.status,","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/chatboxai/chatbox/blob/81571269addb6bafb589a920b2883f1e1e084fd1/src/main/knowledge-base/ipc-handlers.ts#L362-L398","documentation":"Thrown by postLicense() in native-license.ts when the Chatbox license endpoint (/api/license/activate|validate|deactivate) returns a non-2xx response. The message is either the server-provided `payload.error` string (if the body is `{ error: string }`) or the generic `License request failed with status <code>`. Affects license activation, validation, and deactivation flows on the RN mobile shell and the renderer (via packages/remote).","triggerScenarios":"License key is invalid/already-activated/expired (server returns 4xx with `{ error: '...' }`); instance limit reached for the key; license server unreachable but a proxy returned a non-2xx; apiOrigin misconfigured (wrong Chatbox API host) hitting a 404; rate-limited by the license endpoint; revoked license returns a structured error.","commonSituations":"User pastes a typo'd license key; key activated on too many devices; license expired; self-hosted/custom apiOrigin set incorrectly; corporate proxy blocks api.chatboxai.app and returns its own error JSON; validate called with an instanceId from a different key.","solutions":["Read the message: if it is the server's `error` string (e.g. 'license_key_not_found'), surface it directly; if it is the generic 'failed with status N', inspect N (404 → wrong apiOrigin, 429 → rate limit, 5xx → transient).","Verify the license key matches the product (Pro vs Lite) and is not already activated on the max number of devices (deactivate elsewhere first).","Confirm `apiOrigin` (when overridden) points at the real Chatbox license API; leave it unset to use the default `https://api.chatboxai.app`.","For transient 5xx, retry the activate/validate call with backoff; for 4xx licensing errors, do not retry — prompt the user."],"exampleFix":"// before\nawait activateNativeLicense(key, instanceName)\n\n// after\ntry {\n  const r = await activateNativeLicense(key, instanceName)\n  if (!r.valid) showLicenseError(r.error || 'Invalid license')\n} catch (e) {\n  if (/status 5\\d\\d$/.test((e as Error).message)) await retryWithBackoff(() => activateNativeLicense(key, instanceName))\n  else showLicenseError((e as Error).message)\n}","handlingStrategy":"try-catch","validationCode":"function isTransientLicenseError(e: unknown): boolean {\n  return e instanceof Error && /status 5\\d\\d$/.test(e.message)\n}","typeGuard":"function isLicenseError(e: unknown): e is Error {\n  return e instanceof Error && (e.message.includes('License request failed') || /license/i.test(e.message))\n}","tryCatchPattern":"try {\n  return await activateNativeLicense(key, instanceName)\n} catch (e) {\n  if (isTransientLicenseError(e)) return await retryWithBackoff(() => activateNativeLicense(key, instanceName))\n  showLicenseError((e as Error).message)\n  throw e\n}","preventionTips":["Validate the license key format client-side before calling the API.","Leave apiOrigin unset to use the default Chatbox API host.","Deactivate licenses on devices before reactivating elsewhere to avoid instance-limit errors.","Retry only on 5xx; surface 4xx license errors to the user."],"tags":["license","chatbox-ai","http","activation","configuration"],"backgroundTag":null,"analyzedSha":"81571269addb6bafb589a920b2883f1e1e084fd1","analyzedAt":"2026-08-12T21:51:44.981Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}