gastownhall/beads · error
set repo mtime: %w
Error message
set repo mtime: %w
What it means
SetRepoMtimeInTx writes a row into the repo_mtimes cache table (repo_path, jsonl_path, mtime_ns, last_checked) using INSERT ... ON DUPLICATE KEY UPDATE, and wraps any SQL failure with "set repo mtime: %w". This cache lets bd skip re-reading .beads/issues.jsonl when its mtime is unchanged. The error means the underlying Dolt/MySQL statement failed inside the caller's transaction.
Source
Thrown at internal/storage/issueops/bulk_ops.go:436
`SELECT mtime_ns FROM repo_mtimes WHERE repo_path = ?`, repoPath).Scan(&mtimeNs)
if err != nil {
return 0, nil
}
return mtimeNs, nil
}
// SetRepoMtimeInTx upserts the mtime cache for a repo path.
func SetRepoMtimeInTx(ctx context.Context, tx *sql.Tx, repoPath, jsonlPath string, mtimeNs int64) error {
_, err := tx.ExecContext(ctx, `
INSERT INTO repo_mtimes (repo_path, jsonl_path, mtime_ns, last_checked)
VALUES (?, ?, ?, NOW())
ON DUPLICATE KEY UPDATE
jsonl_path = VALUES(jsonl_path),
mtime_ns = VALUES(mtime_ns),
last_checked = NOW()
`, repoPath, jsonlPath, mtimeNs)
if err != nil {
return fmt.Errorf("set repo mtime: %w", err)
}
return nil
}
// ClearRepoMtimeInTx removes the mtime cache entry for a repo path.
func ClearRepoMtimeInTx(ctx context.Context, tx *sql.Tx, repoPath string) error {
// Expand ~ and resolve to absolute path to match stored format.
absPath := expandAndAbsPath(repoPath)
_, err := tx.ExecContext(ctx, `DELETE FROM repo_mtimes WHERE repo_path = ?`, absPath)
if err != nil {
return fmt.Errorf("clear repo mtime: %w", err)
}
return nil
}
func expandAndAbsPath(p string) string {
if strings.HasPrefix(p, "~") {
home, err := os.UserHomeDir()View on GitHub (pinned to 71377f2769)
Solutions
- Run the bd schema migrations so the repo_mtimes table exists (bd doctor / migrate).
- Retry the enclosing transaction; transient connection or lock-wait errors resolve on retry.
- Verify the transaction has not already been rolled back before calling SetRepoMtimeInTx.
- Inspect the wrapped %w error: 'table doesn't exist' -> migrate; 'lock wait timeout' -> shorten transaction or check for stuck writers.
- Check context cancellation deadlines on the calling sync operation.
Example fix
// before
if err := issueops.SetRepoMtimeInTx(ctx, tx, repoPath, jsonlPath, mtimeNs); err != nil {
return err // lost transaction already rolled back
}
// after
if err := issueops.SetRepoMtimeInTx(ctx, tx, repoPath, jsonlPath, mtimeNs); err != nil {
tx.Rollback() // release locks before returning
return fmt.Errorf("update mtime cache: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if err := bdDoctorCheck(); err != nil { /* schema/migration issue */ }
if ctx.Err() != nil { return ctx.Err() } Try / catch
if err := issueops.SetRepoMtimeInTx(ctx, tx, repoPath, jsonlPath, mtimeNs); err != nil {
var se *string
_ = se
tx.Rollback()
return fmt.Errorf("mtime cache update failed (will be rebuilt on next sync): %w", err)
} Prevention
- Keep bd upgraded so schema migrations run before cache tables are used.
- Never reuse a transaction after any prior statement error.
- Pass a live (non-cancelled) context into sync operations.
- Treat mtime-cache failures as non-fatal where possible: the cache is rebuildable.
When it happens
Trigger: Calling SetRepoMtimeInTx when: the repo_mtimes table does not exist (schema not migrated), the transaction is already aborted/rolled back, a duplicate-key conflict cannot be resolved (e.g. repo_path uniqueness violation from differently-normalized paths), the context is cancelled, or the DB connection is lost mid-transaction.
Common situations: Running an older database missing the repo_mtimes migration; passing a repoPath whose normalized form collides with another stored entry; long-running transactions timing out; cancelling a sync command mid-flight; DB restart during bulk import.
Related errors
- clear repo mtime: %w
- failed to claim issue: %w
- get dependent records from %s: %w
- count wisp-only dependent records: %w
- count dependent records from %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/75514572a9c1e583.
Report an issue: GitHub.