{"record":{"id":"9cc8cc7146189b8f","repo":"vitessio/vitess","slug":"insertrecoverydetection-no-detection-id-returned","errorCode":null,"errorMessage":"InsertRecoveryDetection: no detection_id returned for alias=%s analysis=%s","messagePattern":"InsertRecoveryDetection: no detection_id returned for alias=(.+?) analysis=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtorc/logic/topology_recovery_dao.go","lineNumber":73,"sourceCode":"\t\t\t?,\n\t\t\tDATETIME('now')\n\t\t)\n\t\tON CONFLICT(alias, analysis) DO UPDATE\n\t\tSET detection_timestamp = DATETIME('now'),\n\t\t    keyspace = excluded.keyspace,\n\t\t    shard = excluded.shard\n\t\tRETURNING detection_id`,\n\t\tsqlutils.Args(aliasStr, analysisStr, analysisEntry.AnalyzedKeyspace, analysisEntry.AnalyzedShard),\n\t\tfunc(m sqlutils.RowMap) error {\n\t\t\tanalysisEntry.RecoveryId = m.GetInt64(\"detection_id\")\n\t\t\treturn nil\n\t\t})\n\tif err != nil {\n\t\tlog.Error(err.Error())\n\t\treturn err\n\t}\n\tif analysisEntry.RecoveryId == 0 {\n\t\terr = fmt.Errorf(\"InsertRecoveryDetection: no detection_id returned for alias=%s analysis=%s\", aliasStr, analysisStr)\n\t\tlog.Error(err.Error())\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc writeTopologyRecovery(topologyRecovery *TopologyRecovery) (*TopologyRecovery, error) {\n\tanalysisEntry := topologyRecovery.AnalysisEntry\n\tsqlResult, err := db.ExecVTOrc(`INSERT OR IGNORE\n\t\tINTO topology_recovery (\n\t\t\trecovery_id,\n\t\t\talias,\n\t\t\tstart_recovery,\n\t\t\tanalysis,\n\t\t\tkeyspace,\n\t\t\tshard,\n\t\t\tdetection_id\n\t\t) VALUES (","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtorc/logic/topology_recovery_dao.go#L55-L91","documentation":"InsertRecoveryDetection records a newly detected recovery incident in the vtorc backend and expects the INSERT to return the new detection id (stored as analysisEntry.RecoveryId). If the insert succeeds but returns no id (RecoveryId == 0), VTOrc treats it as an inconsistent write and errors out so the incident is not tracked with a dangling identity.","triggerScenarios":"executeCheckAndRecoverFunction (or tests) calls InsertRecoveryDetection and the underlying DAO insert (Generate/RETURNING detection_id style query) does not yield a row id — e.g. backend lacks RETURNING support semantics, or the write was a no-op update on an existing detection.","commonSituations":"Running against an unexpected/older backend that doesn't return last-insert-id as expected; a race where another VTOrc instance inserted the same detection concurrently; DB driver/version quirks with LAST_INSERT_ID().","solutions":["Check VTOrc logs for the logged error and inspect the DB to see whether the detection row was actually inserted","Confirm the backend supports returning the inserted id (MySQL LAST_INSERT_ID) and the DAO query is intact for your Vitess version","Resolve concurrent VTOrc instances writing the same detection; ensure only one instance owns recovery per cluster","Restart VTOrc to re-detect and insert the incident cleanly; delete orphan detection rows if needed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure backend supports returning insert ids\nvar id int64\nif err := db.QueryRow(\"SELECT LAST_INSERT_ID()\").Scan(&id); err != nil || id == 0 {\n    return fmt.Errorf(\"backend cannot return detection id\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run only one VTOrc per cluster to avoid duplicate detections","Verify DAO queries after Vitess upgrades","Clean orphan detection rows periodically"],"tags":["vtorc","database","dao"],"backgroundTag":"insert-returned-no-id","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}