{"record":{"id":"8d9b91352df8c26b","repo":"MHSanaei/3x-ui","slug":"open-postgres-source-w","errorCode":null,"errorMessage":"open postgres source: %w","messagePattern":"open postgres source: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/database/migrate_data.go","lineNumber":170,"sourceCode":"// ExportPostgresToSQLite copies every row from the PostgreSQL database described\n// by srcDSN into a fresh SQLite file at dstPath. It is the reverse of\n// MigrateData and is used to hand a PostgreSQL-backed panel a portable .db file.\n// dstPath is created/overwritten; the PostgreSQL source is left untouched.\nfunc ExportPostgresToSQLite(srcDSN, dstPath string) error {\n\tif srcDSN == \"\" {\n\t\treturn errors.New(\"source DSN is required\")\n\t}\n\tif err := os.MkdirAll(path.Dir(dstPath), 0o755); err != nil {\n\t\treturn err\n\t}\n\t// Start from an empty file so AutoMigrate creates the canonical schema.\n\tif err := os.Remove(dstPath); err != nil && !os.IsNotExist(err) {\n\t\treturn err\n\t}\n\n\tsrc, err := gorm.Open(postgres.Open(srcDSN), &gorm.Config{Logger: logger.Discard})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open postgres source: %w\", err)\n\t}\n\tsrcSQL, err := src.DB()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer srcSQL.Close()\n\n\t// No WAL: keep all data in the main file so it is complete once closed.\n\tdst, err := gorm.Open(sqlite.Open(dstPath+\"?_busy_timeout=10000\"), &gorm.Config{Logger: logger.Discard})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open sqlite destination: %w\", err)\n\t}\n\tdstSQL, err := dst.DB()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer dstSQL.Close()\n","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/database/migrate_data.go#L152-L188","documentation":"Thrown by the PostgreSQL-to-SQLite export path when gorm.Open(postgres.Open(srcDSN)) cannot establish the source connection. GORM defers real connection, so this usually surfaces the driver's dial error: unreachable host, auth failure, unknown database, or TLS mismatch. Nothing has been written to the destination file yet when this fires.","triggerScenarios":"Passing a malformed or wrong-format srcDSN; Postgres not running / firewalled; wrong password or user; database name typo; sslmode unsupported by the server (e.g. sslmode=require against a TLS-less server); DNS resolution failure.","commonSituations":"Exporting a backup from a remote/cloud Postgres whose pg_hba.conf or security group blocks the host; copying a DSN with URL-encoded special characters that got double-encoded; using a read-replica DSN whose credentials differ.","solutions":["Test the exact DSN outside the panel: psql \"$SRC_DSN\" -c 'SELECT 1' — if psql fails, fix the DSN/host/credentials first.","Check server reachability (port open, security groups, pg_hba.conf entry for your client IP).","Match sslmode to the server (disable/require/verify-full) and URL-encode special characters in the password.","Confirm the database exists and the user has CONNECT privilege on it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify the source DSN connects BEFORE starting any export\nsqlDB, err := sql.Open(\"pgx\", srcDSN)\nif err != nil { return err }\ndefer sqlDB.Close()\nif err := sqlDB.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"source DSN unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always test the DSN with psql or a Ping before invoking the export.","URL-encode special characters in passwords inside DSNs.","Match sslmode to the server's TLS configuration."],"tags":["database","postgres","dsn","connection","gorm"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}