{"record":{"id":"573a9004e71d2675","repo":"temporalio/temporal","slug":"unable-to-upsert-workflow-execution-w","errorCode":null,"errorMessage":"unable to upsert workflow execution: %w","messagePattern":"unable to upsert workflow execution: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/sql/sqlplugin/mysql/visibility.go","lineNumber":158,"sourceCode":"\tdb, err := mdb.handle.DB()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttx, err := db.BeginTxx(ctx, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() {\n\t\terr := tx.Rollback()\n\t\t// If the error is sql.ErrTxDone, it means the transaction already closed, so ignore error.\n\t\tif err != nil && !errors.Is(err, sql.ErrTxDone) {\n\t\t\t// Transaction rollback error should never happen, unless db connection was lost.\n\t\t\tretError = fmt.Errorf(\"transaction rollback failed: %w\", retError)\n\t\t}\n\t}()\n\tresult, err = tx.NamedExecContext(ctx, templateUpsertWorkflowExecution, finalRow)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to upsert workflow execution: %w\", err)\n\t}\n\t_, err = tx.NamedExecContext(ctx, templateUpsertCustomSearchAttributes, finalRow)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to upsert custom search attributes: %w\", err)\n\t}\n\t_, err = tx.NamedExecContext(ctx, templateUpsertChasmSearchAttributes, finalRow)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to upsert chasm search attributes: %w\", err)\n\t}\n\terr = tx.Commit()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// DeleteFromVisibility deletes a row from visibility table if it exist\nfunc (mdb *db) DeleteFromVisibility(","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/sql/sqlplugin/mysql/visibility.go#L140-L176","documentation":"ReplaceIntoVisibility performs an upsert (INSERT ... ON DUPLICATE KEY UPDATE) into the executions visibility table as the first statement of its transaction. Failure here is wrapped as 'unable to upsert workflow execution' and aborts the whole visibility write. It wraps whatever MySQL error occurred — constraints, schema mismatch, dead connection.","triggerScenarios":"Calling ReplaceIntoVisibility (workflow close/update) where the upsert into visibility_workflow_executions fails: lock wait timeout on a contended row, data-too-long on a column, unknown column from stale schema, or connection loss.","commonSituations":"High update rate on the same visibility row causing lock contention/timeouts (e.g. many updates to one workflow); visibility schema behind the server version; oversized payload from very long run IDs or search attributes.","solutions":["Read the wrapped MySQL error: lock wait timeout vs data truncation vs schema errors require different fixes.","Apply visibility schema migrations to match the server version.","For lock timeouts, check for long transactions/contended rows on visibility_workflow_executions (SHOW ENGINE INNODB STATUS, innodb_lock_wait_timeout).","Check column size limits against the row values (RunID, WorkflowType, search attribute blobs).","Verify DB connectivity if the cause is a driver error."],"exampleFix":"// before: schema behind server\n// after\ntemporal-sql-tool -plugin mysql -ep $DB_HOST -u $DB_USER -p $DB_PWD update-schema -d temporal_visibility","handlingStrategy":"try-catch","validationCode":"// Go: preflight schema + connectivity check\nvar v string\nif err := visDB.GetContext(ctx, &v, \"SELECT version_ref FROM schema_version\"); err != nil {\n    logger.Fatal(\"cannot read visibility schema version; check DB connectivity/migrations\")\n}","typeGuard":null,"tryCatchPattern":"if err := db.ReplaceIntoVisibility(ctx, row); err != nil {\n    if strings.Contains(err.Error(), \"unable to upsert workflow execution\") {\n        var mysqlErr *mysql.MySQLError\n        if errors.As(err, &mysqlErr) && mysqlErr.Number == 1205 {\n            logger.Warn(\"lock wait timeout on visibility upsert\", tag.Error(err))\n        }\n        return convertPersistenceErr(err)\n    }\n    return err\n}","preventionTips":["Run update-schema on the visibility store after every server upgrade.","Watch for lock contention on hot visibility rows; raise innodb_lock_wait_timeout only after investigating.","Keep column data (run IDs, types, SAs) within schema size limits.","Alert on persistence error metrics for the visibility store."],"tags":["mysql","visibility","upsert","schema"],"backgroundTag":"sql-upsert-failed","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}