{"record":{"id":"0bf40abe1067a16e","repo":"gastownhall/beads","slug":"probe-memory-row-s-w","errorCode":null,"errorMessage":"probe memory row %s: %w","messagePattern":"probe memory row (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/memoryops/memories.go","lineNumber":166,"sourceCode":"\treturn MemoriesFromConfig(all), nil\n}\n\n// configRowExistsInTx reports whether the row is there, regardless of what it\n// holds.\n//\n// issueops.GetConfigInTx cannot answer this: it maps a missing row to \"\" and is\n// right to, because every other caller wants a value. Replaced is a statement\n// about the ROW, so this role needs the distinction that helper deliberately\n// drops — hence the one query in this package that is not composed from the\n// shared config helpers.\nfunc configRowExistsInTx(ctx context.Context, tx *sql.Tx, storageKey string) (bool, error) {\n\tvar one int\n\terr := tx.QueryRowContext(ctx, \"SELECT 1 FROM config WHERE `key` = ?\", storageKey).Scan(&one)\n\tif errors.Is(err, sql.ErrNoRows) {\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"probe memory row %s: %w\", storageKey, err)\n\t}\n\treturn true, nil\n}\n","sourceCodeStart":148,"sourceCodeEnd":170,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/memoryops/memories.go#L148-L170","documentation":"configRowExistsInTx probes `SELECT 1 FROM config WHERE key = ?` to learn whether a memory row physically exists (RememberInTx needs row-existence semantics that GetConfigInTx deliberately collapses to empty-string). This error wraps any probe failure that is not sql.ErrNoRows — a real database error while probing the config table.","triggerScenarios":"Calling RememberInTx when the config-table probe fails: the config table is missing/corrupt, the connection dies, the transaction was already aborted/rolled back by a prior error, or the DB user lacks SELECT on config.","commonSituations":"Embedded Dolt DB mid-migration without the config table; transaction invalidated by an earlier failed statement in the same tx (MySQL/Dolt abort the tx); read-only replica or permissions change blocking SELECT.","solutions":["Check the wrapped driver error; if it says a transaction is aborted, fix/avoid the earlier statement that poisoned the tx and rerun within a fresh transaction","Verify the config table exists and the schema is current (run migrations)","Confirm SELECT permission on the config table for the DB user","Retry RememberInTx after restoring connectivity if the cause was a dropped connection"],"exampleFix":"// before\n_, err := memoryops.RememberInTx(ctx, brokenTx, key, value) // tx already aborted\n// after\nerr := store.RunInTransaction(ctx, \"remember\", func(tx storage.Transaction) error {\n\t_, err := memoryops.RememberInTx(ctx, tx, key, value)\n\treturn err\n})","handlingStrategy":"try-catch","validationCode":"// run within a fresh transaction and confirm migrations applied\nif err := store.RunMigrations(ctx); err != nil { return err }","typeGuard":null,"tryCatchPattern":"err := store.RunInTransaction(ctx, \"remember\", func(tx storage.Transaction) error {\n\tif _, err := memoryops.RememberInTx(ctx, tx, key, val); err != nil {\n\t\tif strings.Contains(err.Error(), \"probe memory row\") {\n\t\t\t// config table issue: check schema/permissions\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n})","preventionTips":["Never reuse a transaction after a failed statement — start a fresh one","Keep schema migrations current so the config table exists","Grant the app role SELECT on config","Health-check the store before write paths that depend on probe queries"],"tags":["database","memory-plane","config-probe"],"backgroundTag":"db-probe-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}