{"record":{"id":"bd8f339e1a5f0053","repo":"gastownhall/beads","slug":"db-labelsqlrepository-insert-s-s-rows-affected","errorCode":null,"errorMessage":"db: LabelSQLRepository.Insert %s/%s: rows affected: %w","messagePattern":"db: LabelSQLRepository\\.Insert (.+?)/(.+?): rows affected: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/label.go","lineNumber":60,"sourceCode":"\t// Reject an over-length label before the INSERT IGNORE, which would otherwise\n\t// silently truncate it to the VARCHAR(255) column. This is the proxied-server\n\t// (uow) analog of issueops.AddLabelInTx's guard, so both write stacks return a\n\t// typed ErrFieldTooLong instead of storing a label the caller never sent.\n\tif err := types.CheckFieldLen(\"label\", label); err != nil {\n\t\treturn err\n\t}\n\ttable := pickLabelTable(opts.UseWispsTable)\n\t//nolint:gosec // G201: table is one of two hardcoded constants\n\tresult, err := r.runner.ExecContext(ctx,\n\t\tfmt.Sprintf(\"INSERT IGNORE INTO %s (issue_id, label) VALUES (?, ?)\", table),\n\t\tissueID, label,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: %w\", issueID, label, err)\n\t}\n\trows, err := result.RowsAffected()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: rows affected: %w\", issueID, label, err)\n\t}\n\tif rows == 0 {\n\t\tissueTable := \"issues\"\n\t\tif opts.UseWispsTable {\n\t\t\tissueTable = \"wisps\"\n\t\t}\n\t\tvar count int\n\t\t//nolint:gosec // G201: issueTable is one of two hardcoded constants.\n\t\tif err := r.runner.QueryRowContext(ctx, fmt.Sprintf(\"SELECT COUNT(*) FROM %s WHERE id = ?\", issueTable), issueID).Scan(&count); err != nil {\n\t\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: verify issue: %w\", issueID, label, err)\n\t\t}\n\t\tif count == 0 {\n\t\t\treturn fmt.Errorf(\"db: LabelSQLRepository.Insert %s/%s: issue does not exist\", issueID, label)\n\t\t}\n\t\treturn nil\n\t}\n\tif err := r.events.Record(ctx, domain.Event{\n\t\tIssueID:  issueID,","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/label.go#L42-L78","documentation":"Thrown when result.RowsAffected() fails after the INSERT IGNORE in LabelSQLRepository.Insert. The driver failed to report how many rows the insert touched, so the repository cannot tell whether the label was actually added and cannot safely journal the EventLabelAdded event.","triggerScenarios":"Calling Insert against a driver/connection that errors on RowsAffected (e.g. broken connection returned before metadata, or a driver wrapper that does not implement RowsAffected for INSERT IGNORE results).","commonSituations":"Stale pooled connection that died between ExecContext and RowsAffected; mismatched or buggy driver version; result object from a mock/test double lacking RowsAffected support.","solutions":["Retry the insert; transient connection drops often recover","Check DB connectivity and reconnect the pool","Verify the Dolt driver version is current","If in tests, ensure the mock result implements RowsAffected"],"exampleFix":"// before\nrows, err := result.RowsAffected()\nif err != nil { return fmt.Errorf(\"... rows affected: %w\", err) }\n// after\ndb := sqlx.NewDb(conn, \"mysql\"); db.SetConnMaxLifetime(30 * time.Second) // avoid stale connections\nrows, err := result.RowsAffected()","handlingStrategy":"retry","validationCode":"if err := db.PingContext(ctx); err != nil { return fmt.Errorf(\"db unavailable: %w\", err) }","typeGuard":null,"tryCatchPattern":"err := repo.Insert(ctx, issueID, label, opts)\nfor i := 0; i < 3 && err != nil; i++ {\n    time.Sleep(backoff(i))\n    err = repo.Insert(ctx, issueID, label, opts)\n}","preventionTips":["Set ConnMaxLifetime to recycle stale pooled connections","Retry idempotent inserts on transient driver errors","Keep the Dolt driver up to date","Avoid long-lived idle connections behind NAT/firewalls"],"tags":["database","sql","rows-affected","driver"],"backgroundTag":"rows-affected-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}