FlowiseAI/Flowise · error · Error

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

Error message

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

What it means

SQLite analog of errors 263/268. Thrown in SQLiteRecordManager.update when timeAtLeast is set and the DB clock is older. Note: SQLite time comes from the same process (the file is local), so this almost always indicates the local system clock is behind, or the caller passed an unreasonable timeAtLeast.

Source

Thrown at packages/components/nodes/recordmanager/SQLiteRecordManager/SQLiteRecordManager.ts:251

            throw error
        } 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. Check the system clock and NTP sync.
  2. Drop timeAtLeast from updateOptions if not needed.
  3. In tests, freeze both this.getTime()'s source and timeAtLeast consistently.

Example fix

// before
await mgr.update(keys, { timeAtLeast: futureTimestamp })
// after
await mgr.update(keys)
Defensive patterns

Strategy: validation

Validate before calling

// For SQLite the clock is local; ensure system time is sane.
const now = Date.now()
if (timeAtLeast && timeAtLeast > now) {
  throw new Error('timeAtLeast is in the future relative to local clock.')
}

Type guard

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

Try / catch

try {
  await manager.update(keys, { timeAtLeast })
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Time sync issue')) {
    // for SQLite this is local clock skew; sync NTP or drop timeAtLeast
  }
  throw e
}

Prevention

When it happens

Trigger: Local machine clock set ahead of when records were last written; caller passed a future timestamp; VM/container clock drift; testing with mocked clocks.

Common situations: Developer laptop clock skewed; CI runner clock drift; unit tests with hardcoded future timestamps.

Related errors


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