{"record":{"id":"0cbb1dd73d93facd","repo":"golang-migrate/migrate","slug":"conn-v-db-v-0cbb1d","errorCode":null,"errorMessage":"conn: %v, db: %v","messagePattern":"conn: (.+?), db: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"database/snowflake/snowflake.go","lineNumber":155,"sourceCode":"\n\tmigrationsTable := purl.Query().Get(\"x-migrations-table\")\n\n\tpx, err := WithInstance(db, &Config{\n\t\tDatabaseName:    database,\n\t\tMigrationsTable: migrationsTable,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn px, nil\n}\n\nfunc (p *Snowflake) Close() error {\n\tconnErr := p.conn.Close()\n\tdbErr := p.db.Close()\n\tif connErr != nil || dbErr != nil {\n\t\treturn fmt.Errorf(\"conn: %v, db: %v\", connErr, dbErr)\n\t}\n\treturn nil\n}\n\nfunc (p *Snowflake) Lock() error {\n\tif !p.isLocked.CompareAndSwap(false, true) {\n\t\treturn database.ErrLocked\n\t}\n\treturn nil\n}\n\nfunc (p *Snowflake) Unlock() error {\n\tif !p.isLocked.CompareAndSwap(true, false) {\n\t\treturn database.ErrNotLocked\n\t}\n\treturn nil\n}\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/database/snowflake/snowflake.go#L137-L173","documentation":"Close() on the Snowflake driver closes both the underlying database/sql connection pool and the native gosnowflake connection. If either Close returns an error, the driver combines both messages into a single error via fmt.Errorf(\"conn: %v, db: %v\", connErr, dbErr). Note that a nil error formats as \"<nil>\", so the message tells you which of the two resources actually failed.","triggerScenarios":"Calling database.Driver.Close() (e.g. via migrate.Close()) when p.conn.Close() and/or p.db.Close() returns a non-nil error — typically a network failure talking to Snowflake, an already-closed connection, or a driver-level teardown error.","commonSituations":"Network blips or firewall drops between the app and the Snowflake account at teardown; closing migrate twice (second Close hits closed connections); Snowflake warehouse/session being terminated server-side before Close; TLS/token expiration mid-session.","solutions":["Read the \"conn:\" and \"db:\" fields in the message to identify which resource failed; a \"<nil>\" field means that part succeeded.","Ensure Close() is called only once per driver instance (migrate instance); guard with sync.Once if teardown may race.","Check network connectivity/VPN/proxy to the Snowflake account and that the warehouse/session is still alive at shutdown time.","If the error is benign (session already terminated server-side), log and treat Close failure as non-fatal, since migrations may already be committed.","Upgrade github.com/snowflakedb/gosnowflake; older versions had spurious Close errors."],"exampleFix":"// before\nif err := m.Close(); err != nil {\n    log.Fatal(err) // treats any teardown hiccup as fatal\n}\n// after\nif err := m.Close(); err != nil {\n    log.Printf(\"non-fatal close error (migrations already applied): %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"if m != nil {\n    // only close once; use sync.Once in app code\n    var once sync.Once\n    once.Do(func() { _ = m.Close() })\n}","typeGuard":"func isCloseErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"conn:\")\n}","tryCatchPattern":"if err := m.Close(); err != nil {\n    // message is 'conn: %v, db: %v' — <nil> means that part succeeded\n    log.Printf(\"migrate close (non-fatal, migrations persisted): %v\", err)\n}","preventionTips":["Close each migrate instance exactly once (guard with sync.Once).","Keep network to Snowflake alive until after Close; don't terminate sessions server-side first.","Treat teardown errors as non-fatal when migrations have already been committed.","Keep gosnowflake updated to reduce spurious Close errors."],"tags":["snowflake","close","connection-teardown","go"],"backgroundTag":"connection-close-error","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}