{"record":{"id":"75514572a9c1e583","repo":"gastownhall/beads","slug":"set-repo-mtime-w","errorCode":null,"errorMessage":"set repo mtime: %w","messagePattern":"set repo mtime: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/bulk_ops.go","lineNumber":436,"sourceCode":"\t\t`SELECT mtime_ns FROM repo_mtimes WHERE repo_path = ?`, repoPath).Scan(&mtimeNs)\n\tif err != nil {\n\t\treturn 0, nil\n\t}\n\treturn mtimeNs, nil\n}\n\n// SetRepoMtimeInTx upserts the mtime cache for a repo path.\nfunc SetRepoMtimeInTx(ctx context.Context, tx *sql.Tx, repoPath, jsonlPath string, mtimeNs int64) error {\n\t_, err := tx.ExecContext(ctx, `\n\t\tINSERT INTO repo_mtimes (repo_path, jsonl_path, mtime_ns, last_checked)\n\t\tVALUES (?, ?, ?, NOW())\n\t\tON DUPLICATE KEY UPDATE\n\t\t\tjsonl_path = VALUES(jsonl_path),\n\t\t\tmtime_ns = VALUES(mtime_ns),\n\t\t\tlast_checked = NOW()\n\t`, repoPath, jsonlPath, mtimeNs)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"set repo mtime: %w\", err)\n\t}\n\treturn nil\n}\n\n// ClearRepoMtimeInTx removes the mtime cache entry for a repo path.\nfunc ClearRepoMtimeInTx(ctx context.Context, tx *sql.Tx, repoPath string) error {\n\t// Expand ~ and resolve to absolute path to match stored format.\n\tabsPath := expandAndAbsPath(repoPath)\n\t_, err := tx.ExecContext(ctx, `DELETE FROM repo_mtimes WHERE repo_path = ?`, absPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"clear repo mtime: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc expandAndAbsPath(p string) string {\n\tif strings.HasPrefix(p, \"~\") {\n\t\thome, err := os.UserHomeDir()","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/bulk_ops.go#L418-L454","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nif err := issueops.SetRepoMtimeInTx(ctx, tx, repoPath, jsonlPath, mtimeNs); err != nil {\n    return err // lost transaction already rolled back\n}\n// after\nif err := issueops.SetRepoMtimeInTx(ctx, tx, repoPath, jsonlPath, mtimeNs); err != nil {\n    tx.Rollback() // release locks before returning\n    return fmt.Errorf(\"update mtime cache: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if err := bdDoctorCheck(); err != nil { /* schema/migration issue */ }\nif ctx.Err() != nil { return ctx.Err() }","typeGuard":null,"tryCatchPattern":"if err := issueops.SetRepoMtimeInTx(ctx, tx, repoPath, jsonlPath, mtimeNs); err != nil {\n    var se *string\n    _ = se\n    tx.Rollback()\n    return fmt.Errorf(\"mtime cache update failed (will be rebuilt on next sync): %w\", err)\n}","preventionTips":["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."],"tags":["database","storage","sql","cache"],"backgroundTag":"sql-exec-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}