paperclipai/paperclip · warning

failed company transfer runs stranded in applying by a…

Error message

failed company transfer runs stranded in applying by a restart

What it means

Company-transfer apply jobs are in-memory in the single server process. At startup, recoverStrandedApplyingRuns fails any run still marked 'applying' — those were interrupted by the previous shutdown and would otherwise 409 on every retry forever. Their spooled transfer parts remain reusable, and this warning lists the recovered run ids.

Solutions

  1. Retry the company transfers whose runIds appear in the warning — spooled parts make the retry cheap.
  2. Before planned restarts, let in-flight transfers finish (maintenance window / drain) to avoid stranding.
  3. If the restart was unexpected, check the previous process's logs for the crash cause.
  4. Do not hand-edit the runs' DB state — recovery already failed them cleanly.
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: The server process restarted (deploy, crash, OOM kill, container restart) while a company import transfer was in its 'applying' phase; on next boot those runs are failed and listed in the warn.

Common situations: Rolling deploys landing during active imports; crashes mid-apply; aggressive container restart policies; host reboots during bulk company imports.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18). Data as JSON: /api/errors/c97d5768b9523854. Report an issue: GitHub.

Appendix: source

Thrown at server/src/app.ts:870

    if (feedbackExportTimer) {
      clearInterval(feedbackExportTimer);
      feedbackExportTimer = null;
    }
  };
  const flushPendingFeedbackExports = async () => {
    if (feedbackExportShuttingDown) return;
    try {
      await opts.feedbackExportService?.flushPendingFeedbackTraces();
    } catch (err) {
      if (isDatabaseConnectionUnavailableError(err)) {
        disableFeedbackExportFlushes();
        logger.warn({ err }, "Disabling pending feedback export flushes because the database is unavailable");
        return;
      }
      logger.error({ err }, "Failed to flush pending feedback exports");
    }
  };

  feedbackExportTimer = opts.feedbackExportService
    ? setInterval(() => {
      void flushPendingFeedbackExports();
    }, FEEDBACK_EXPORT_FLUSH_INTERVAL_MS)
    : null;
  feedbackExportTimer?.unref?.();
  if (opts.feedbackExportService) {
    void flushPendingFeedbackExports();
  }
  // Abandoned chunked-import spool sweep: hourly (plus once at startup),
  // deleting spool dirs whose transfer saw no activity for 24h and cancelling
  // their still-open ledger runs. Same setInterval + unref + shutdown-clear
  // shape as the feedback export flush above.
  const importTransferSpoolRoot = resolveDefaultImportTransferSpoolRoot();
  const sweepImportTransferSpools = () => {
    sweepAbandonedImportTransferSpools(db, importTransferSpoolRoot)
      .then((result) => {
        if (result.swept > 0) {

View on GitHub (pinned to 01ad858492)