FlowiseAI/Flowise · error · Error

Time sync issue with database ${updatedAt} < ${timeAtLeast}

Error message

Time sync issue with database ${updatedAt} < ${timeAtLeast}

What it means

Thrown inside MySQLRecordManager.update when the caller passes updateOptions.timeAtLeast and the database's current time (this.getTime()) is older than that floor. The record manager uses updated_at for staleness checks, so a clock skewed backwards would silently write stale markers; this guard refuses the write.

Source

Thrown at packages/components/nodes/recordmanager/MySQLRecordManager/MySQLrecordManager.ts:306

        } finally {
            await dataSource.destroy()
        }
    }

    async update(keys: Array<{ uid: string; docId: string }> | string[], updateOptions?: UpdateOptions): Promise<void> {
        if (keys.length === 0) {
            return
        }

        const dataSource = await this.getDataSource()
        const queryRunner = dataSource.createQueryRunner()
        const tableName = this.sanitizeTableName(this.tableName)

        const updatedAt = await this.getTime()
        const { timeAtLeast, groupIds: _groupIds } = updateOptions ?? {}

        if (timeAtLeast && updatedAt < timeAtLeast) {
            throw new Error(`Time sync issue with database ${updatedAt} < ${timeAtLeast}`)
        }

        // Handle both new format (objects with uid and docId) and old format (strings)
        const isNewFormat = keys.length > 0 && typeof keys[0] === 'object' && 'uid' in keys[0]
        const keyStrings = isNewFormat ? (keys as Array<{ uid: string; docId: string }>).map((k) => k.uid) : (keys as string[])
        const docIds = isNewFormat ? (keys as Array<{ uid: string; docId: string }>).map((k) => k.docId) : keys.map(() => null)

        const groupIds = _groupIds ?? keyStrings.map(() => null)

        if (groupIds.length !== keyStrings.length) {
            throw new Error(`Number of keys (${keyStrings.length}) does not match number of group_ids (${groupIds.length})`)
        }

        const recordsToUpsert = keyStrings.map((key, i) => [key, this.namespace, updatedAt, groupIds[i] ?? null, docIds[i] ?? null])

        const query = `
            INSERT INTO \`${tableName}\` (\`key\`, \`namespace\`, \`updated_at\`, \`group_id\`, \`doc_id\`)
            VALUES (?, ?, ?, ?, ?)

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Sync clocks: ensure both the Flowise host and the MySQL host run NTP/chrony and agree to within a second.
  2. If skew is expected and acceptable for your workload, drop or relax updateOptions.timeAtLeast.
  3. Verify this.getTime() returns DB time (SELECT NOW()) and not application time; check the getTime implementation.
  4. Restart drifted containers - Docker Desktop especially can drift after host sleep.

Example fix

// before
await mgr.update(keys, { timeAtLeast: Date.now() })
// after - let the manager derive the floor, or pass a value tied to DB time
await mgr.update(keys)
Defensive patterns

Strategy: retry

Validate before calling

// Compare app clock to DB clock before calling update.
const dbNow = await manager.getTime()
const skew = Math.abs(Date.now() - dbNow)
if (skew > 5_000) {
  throw new Error(`Clock skew of ${skew}ms detected; sync NTP before ingesting.`)
}

Type guard

function isReasonableTimestamp(t: unknown, reference: number): t is number {
  return typeof t === 'number' && t <= reference + 60_000
}

Try / catch

// Transient clock skew may resolve via NTP; retry once after a short delay only if skew is small.
try {
  await manager.update(keys, { timeAtLeast })
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Time sync issue')) {
    // re-check skew, resync, and retry once; otherwise surface
  }
  throw e
}

Prevention

When it happens

Trigger: The MySQL server (or its host) clock is behind the Flowise server clock; an NTP sync failure on the DB host; container clock drift; running across VMs in different time sources; the caller passed a future-dated timeAtLeast by mistake.

Common situations: Docker container whose clock drifted; cloud DB failover resetting the time; developer's machine set to a future date; ingestion pipeline computing timeAtLeast from a monotonic clock that outpaced wall-clock.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/f44fdc62905d2376. Report an issue: GitHub.