{"record":{"id":"32b66467b6125083","repo":"gastownhall/beads","slug":"touch-dependency-coordination-for-s-w","errorCode":null,"errorMessage":"touch dependency coordination for %s: %w","messagePattern":"touch dependency coordination for (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_coordination.go","lineNumber":43,"sourceCode":"\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// TouchDependencyCoordinationTableInTx rewrites the coordination cell for one\n// dependency table. table must be dependencies or wisp_dependencies.\nfunc TouchDependencyCoordinationTableInTx(ctx context.Context, tx DBTX, parentID, table string) error {\n\tif parentID == \"\" {\n\t\treturn fmt.Errorf(\"touch dependency coordination: parent ID must not be empty\")\n\t}\n\tif table != dependencyCoordinationDurableTier && table != dependencyCoordinationEphemeralTier {\n\t\treturn fmt.Errorf(\"touch dependency coordination: unsupported table %q\", table)\n\t}\n\tkey := dependencyCoordinationKey(parentID, table)\n\tif _, err := tx.ExecContext(ctx,\n\t\t\"REPLACE INTO local_metadata (`key`, value) VALUES (?, ?)\", key, strconv.FormatInt(FreshRowLock(), 10)); err != nil {\n\t\treturn fmt.Errorf(\"touch dependency coordination for %s: %w\", table, err)\n\t}\n\treturn nil\n}\n\nfunc dependencyCoordinationKey(parentID, table string) string {\n\tshard := dependencyCoordinationShard(parentID)\n\t// A tier has 4096 shard rows: enough to keep unrelated writes apart while\n\t// bounding the clone-local coordination state at 8192 rows. Same-parent\n\t// operations always resolve to the same shard; a hash collision only adds a\n\t// safe serialization conflict.\n\treturn fmt.Sprintf(\"%s%s/%s/%03x\", dependencyCoordinationKeyPrefix, dependencyCoordinationKeyVersion, table, shard)\n}\n\nfunc dependencyCoordinationShard(parentID string) uint16 {\n\tsum := sha256.Sum256([]byte(parentID))\n\treturn uint16(sum[0])<<4 | uint16(sum[1])>>4\n}\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_coordination.go#L25-L61","documentation":"This wraps the underlying SQL error from the REPLACE INTO local_metadata statement that records a fresh coordination/row-lock timestamp for the dependency table. The library wraps (%w) the driver error while naming the affected table so callers can distinguish which dependency tier failed to be touched. It indicates the local metadata write failed at the storage level, not a caller mistake.","triggerScenarios":"Calling TouchDependencyCoordinationTableInTx when the local_metadata table is missing/locked, the transaction is already aborted, or the Dolt driver rejects the write (schema mismatch, disk, connection failure).","commonSituations":"Schema drift where local_metadata doesn't exist in an old database; transaction already rolled back due to an earlier error in the same tx; write contention or read-only database.","solutions":["Read the wrapped root cause — it identifies the driver/SQL failure.","Verify the local_metadata table exists with columns `key` and `value` (bd doctor / schema check).","Check that no earlier statement in the same transaction failed and poisoned the tx.","Retry on transient errors; if persistent, confirm the database isn't read-only or locked."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify local_metadata exists before writing\nvar one int\nif err := tx.QueryRowContext(ctx,\n    \"SELECT 1 FROM local_metadata LIMIT 1\").Scan(&one); err != nil {\n    return fmt.Errorf(\"local_metadata unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := TouchDependencyCoordinationTableInTx(ctx, tx, parentID, table); err != nil {\n    if isTransientSQLErr(err) { err = TouchDependencyCoordinationTableInTx(ctx, tx, parentID, table) }\n    if err != nil { return fmt.Errorf(\"coordination touch failed: %w\", err) }\n}","preventionTips":["Ensure schema migrations create local_metadata on all environments.","Fail the whole transaction cleanly on earlier errors — don't keep writing into an aborted tx.","Check read-only/lock status of the database when the error persists."],"tags":["database","storage","coordination","local-metadata"],"backgroundTag":"sql-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}