{"record":{"id":"71d6a8ffaf601a54","repo":"QuantumNous/new-api","slug":"failed-to-clean-logs","errorCode":null,"errorMessage":"Failed to clean logs","messagePattern":"Failed to clean logs","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"web/src/features/system-settings/maintenance/log-settings-section.tsx","lineNumber":286,"sourceCode":"    if (!purgeTimestamp) {\n      toast.error(t('Select a timestamp before clearing logs.'))\n      return\n    }\n\n    setShowConfirmDialog(true)\n  }\n\n  const handleCleanLogs = async () => {\n    if (!purgeTimestamp) {\n      toast.error(t('Select a timestamp before clearing logs.'))\n      return\n    }\n\n    setIsStartingLogCleanup(true)\n    try {\n      const res = await startLogCleanupTask(purgeTimestamp)\n      if (!res.success) {\n        throw new Error(res.message || t('Failed to clean logs'))\n      }\n      if (!res.data) {\n        throw new Error(t('Failed to clean logs'))\n      }\n      setLogCleanupTask(res.data)\n      setShowConfirmDialog(false)\n      toast.success(t('Log cleanup task started.'))\n    } catch (error) {\n      const message =\n        error instanceof Error ? error.message : t('Failed to clean logs')\n      toast.error(message)\n    } finally {\n      setIsStartingLogCleanup(false)\n    }\n  }\n\n  const cleanupServerLogFiles = async () => {\n    if (","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/QuantumNous/new-api/blob/e2c7aa7b102c2075eae2377df3508658d45e88dc/web/src/features/system-settings/maintenance/log-settings-section.tsx#L268-L304","documentation":"First failure branch of handleCleanLogs: startLogCleanupTask(purgeTimestamp) resolved with success=false, so the code throws using the server's response.message (or the localized fallback). The catch converts it to an error toast; this is the business-error path, not a thrown HTTP error.","triggerScenarios":"POST start-log-cleanup with a timestamp the backend rejects: purge time in the future, insufficient admin permission, a cleanup task already running, or a server-side error enqueuing the task.","commonSituations":"Admin picks a date/time whose timezone conversion lands in the future (frontend sends local-time-derived timestamp); a previous cleanup task is still in progress; token expired mid-session; log DB unreachable.","solutions":["Read the toast — it shows response.message from the server, which names the exact rejection reason.","Ensure the selected timestamp is in the past, accounting for timezone conversion before sending.","Wait for any in-progress cleanup task to finish (the panel tracks it via logCleanupTask state) before starting another.","If the backend reports a DB error, check the log database connection and retry."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before calling startLogCleanupTask, clamp the timestamp to the past\nconst ts = purgeTimestamp instanceof Date ? purgeTimestamp.getTime() : Number(purgeTimestamp)\nif (!Number.isFinite(ts) || ts > Date.now()) {\n  toast.error(t('Select a timestamp before clearing logs.'))\n  return\n}\nconst res = await startLogCleanupTask(ts)","typeGuard":null,"tryCatchPattern":"try {\n  const res = await startLogCleanupTask(purgeTimestamp)\n  if (!res.success) throw new Error(res.message || t('Failed to clean logs'))\n  ...\n} catch (error) {\n  toast.error(error instanceof Error ? error.message : t('Failed to clean logs'))\n}","preventionTips":["Client-side validate that the chosen timestamp is finite and strictly in the past (timezone-aware).","Disable the start button while another cleanup task is active.","Always display response.message from the server; it carries the exact rejection reason."],"tags":["maintenance","log-cleanup","api-error","admin"],"backgroundTag":null,"analyzedSha":"e2c7aa7b102c2075eae2377df3508658d45e88dc","analyzedAt":"2026-08-15T10:35:18.111Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}