HKUDS/DeepTutor · error · LearningConflictError

LearningConflictError(path_id, tx.base_revision…

Error message

LearningConflictError(path_id, tx.base_revision, int(current["revision"]) if current else 0)

What it means

Same optimistic-concurrency check applied to a transaction commit: the UPDATE is guarded by tx.base_revision, and the row's actual revision differs — the path changed underneath the open transaction. LearningConflictError carries path id, base revision, and the actual revision (0 if the row is gone).

Solutions

  1. Catch the conflict, restart the transaction from a fresh load
  2. Hold a path lease for the whole read-modify-write cycle
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at deeptutor/learning/storage.py:597 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/d24ca9eaf3f5a67c. Report an issue: GitHub.

Appendix: source

Thrown at deeptutor/learning/storage.py:597

                    cursor = conn.execute(
                        """
                        UPDATE mastery_paths
                        SET state_json = ?, revision = ?, updated_at = ?
                        WHERE path_id = ? AND revision = ?
                        """,
                        (
                            self._progress_payload(tx.progress, revision, now),
                            revision,
                            now,
                            path_id,
                            tx.base_revision,
                        ),
                    )
                    if cursor.rowcount != 1:
                        current = conn.execute(
                            "SELECT revision FROM mastery_paths WHERE path_id = ?", (path_id,)
                        ).fetchone()
                        raise LearningConflictError(
                            path_id,
                            tx.base_revision,
                            int(current["revision"]) if current else 0,
                        )
                    for event_type, payload, session_id, turn_id in tx.events:
                        conn.execute(
                            """
                            INSERT INTO mastery_events (
                                path_id, revision, event_type, payload_json,
                                session_id, turn_id, created_at
                            ) VALUES (?, ?, ?, ?, ?, ?, ?)
                            """,
                            (
                                path_id,
                                revision,
                                event_type,
                                json.dumps(payload, ensure_ascii=False),
                                session_id,

View on GitHub (pinned to 3e82f13042)