{"record":{"id":"dd029eef8e81e3d4","repo":"micro/go-micro","slug":"failed-to-prepare-write-statement","errorCode":null,"errorMessage":"failed to prepare write statement","messagePattern":"failed to prepare write statement","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"store/mysql/mysql.go","lineNumber":171,"sourceCode":"\n\t// Create a table for the namespace's prefix\n\tcreateSQL := fmt.Sprintf(\"CREATE TABLE IF NOT EXISTS %s (`key` varchar(255) primary key, value blob null, expiry timestamp not null);\", s.table)\n\t_, err = s.db.Exec(createSQL)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Couldn't create table\")\n\t}\n\n\t// prepare statements\n\tvar prepareErr error\n\n\ts.readPrepare, prepareErr = s.db.Prepare(fmt.Sprintf(\"SELECT `key`, value, expiry FROM %s.%s WHERE `key` = ?;\", s.database, s.table))\n\tif prepareErr != nil {\n\t\treturn errors.Wrap(prepareErr, \"failed to prepare read statement\")\n\t}\n\n\ts.writePrepare, prepareErr = s.db.Prepare(fmt.Sprintf(\"INSERT INTO %s.%s (`key`, value, expiry) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE `value`= ?, `expiry` = ?\", s.database, s.table))\n\tif prepareErr != nil {\n\t\treturn errors.Wrap(prepareErr, \"failed to prepare write statement\")\n\t}\n\n\ts.deletePrepare, prepareErr = s.db.Prepare(fmt.Sprintf(\"DELETE FROM %s.%s WHERE `key` = ?;\", s.database, s.table))\n\tif prepareErr != nil {\n\t\treturn errors.Wrap(prepareErr, \"failed to prepare delete statement\")\n\t}\n\n\treturn nil\n}\n\nfunc (s *sqlStore) configure() error {\n\tnodes := s.options.Nodes\n\tif len(nodes) == 0 {\n\t\tnodes = []string{\"localhost:3306\"}\n\t}\n\n\tdatabase := s.options.Database\n\tif len(database) == 0 {","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/store/mysql/mysql.go#L153-L189","documentation":"initDB prepares the INSERT ... ON DUPLICATE KEY UPDATE statement used by sqlStore.Write; a Prepare error means the write path is unusable and configuration fails immediately rather than failing lazily on first Write.","triggerScenarios":"configure() -> initDB() calls s.db.Prepare with the upsert SQL and the MySQL driver/server rejects it — broken connection, invalid `<db>.<table>` identifiers, or server refusing PREPARE.","commonSituations":"Flaky MySQL connectivity during startup; bad namespace chars breaking the interpolated SQL; older MySQL versions or proxies (e.g. some managed tiers) restricting prepared statements.","solutions":["Read the wrapped cause to distinguish connection vs syntax errors","Ensure the namespace/table produce valid SQL identifiers","Reconnect/retry configure; check MySQL server and proxy health","If the proxy forbids prepared statements, switch to a store backend without them"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := db.Ping(); err != nil {\n    return fmt.Errorf(\"mysql unreachable before store configure: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := st.Init(opts...); err != nil {\n    if strings.Contains(err.Error(), \"failed to prepare write statement\") {\n        time.Sleep(time.Second)\n        return st.Init(opts...)\n    }\n    return err\n}","preventionTips":["Verify upsert SQL works on your MySQL version (ON DUPLICATE KEY UPDATE)","Check max_prepared_stmt_count on the server","Use valid identifier namespaces","Add bounded retries around store Init"],"tags":["mysql","store","prepare","sql"],"backgroundTag":"sql-prepare-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}