FreshRSS/FreshRSS · critical · Minz_PDOConnectionException

Invalid database type!

Error message

Invalid database type!

What it means

Minz_ModelPdo::dbConnect() switches on the 'type' entry of the system db configuration and only implements 'sqlite', 'mysql', and 'pgsql' (each constructing the matching Minz_Pdo* subclass with prefix handling). Any other value falls through to Minz_PDOConnectionException('Invalid database type!') carrying the configured DB user, so the connection never opens.

Source

Thrown at lib/Minz/ModelPdo.php:90

				} else {
					$dsn = 'sqlite:' . DATA_PATH . '/users/' . $this->current_user . '/db.sqlite';
				}
				$this->pdo = new Minz_PdoSqlite($dsn . $dsnParams, null, null, $driver_options);
				$this->pdo->setPrefix('');
				break;
			case 'pgsql':
				$dsn = 'pgsql:host=' . (empty($dbServer['host']) ? $db['host'] : $dbServer['host']);
				if (!empty($db['base'])) {
					$dsn .= ';dbname=' . $db['base'];
				}
				if (!empty($dbServer['port'])) {
					$dsn .= ';port=' . $dbServer['port'];
				}
				$this->pdo = new Minz_PdoPgsql($dsn . $dsnParams, $db['user'], $db['password'], $driver_options);
				$this->pdo->setPrefix($db['prefix'] . $this->current_user . '_');
				break;
			default:
				throw new Minz_PDOConnectionException('Invalid database type!', is_string($db['user'] ?? null) ? $db['user'] : '', Minz_Exception::ERROR);
		}
		if (self::$usesSharedPdo) {
			self::$sharedPdo = $this->pdo;
		}
	}

	/**
	 * Create the connection to the database using the variables
	 * HOST, BASE, USER and PASS variables defined in the configuration file
	 * @throws Minz_ConfigurationException
	 * @throws Minz_PDOConnectionException
	 */
	public function __construct(?string $currentUser = null, ?Minz_Pdo $currentPdo = null) {
		if ($currentUser === null) {
			$currentUser = Minz_User::name();
		}
		if ($currentPdo !== null) {
			$this->pdo = $currentPdo;

View on GitHub (pinned to 95842d81c1)

Solutions

  1. Set db.type in data/config.php to exactly one of: sqlite, mysql, pgsql
  2. Start from config.default.php and re-apply only documented overrides instead of hand-writing the whole file
  3. After editing, restart php-fpm/web server so no opcode or config cache serves the old value

Example fix

// data/config.php
// before
'db' => ['type' => 'postgres', 'host' => 'db1', ...],

// after
'db' => ['type' => 'pgsql', 'host' => 'db1', ...],
Defensive patterns

Strategy: validation

Validate before calling

$db = Minz_Configuration::get('system')->db;
if (!in_array($db['type'], ['sqlite', 'mysql', 'pgsql'], true)) {
	// refuse to bootstrap with an unknown type; show a config error instead of a PDO exception
	throw new RuntimeException('Unsupported db.type: ' . $db['type']);
}

Type guard

function isSupportedDatabaseType(mixed $type): bool {
	return is_string($type) && in_array($type, ['sqlite', 'mysql', 'pgsql'], true);
}

Prevention

When it happens

Trigger: data/config.php contains db 'type' => 'postgres', 'mariadb', 'MySQL', or an empty/null value from a broken config; hand-written config after migrating from another tool; a config produced by an incompatible FreshRSS version or a templating typo in a container image.

Common situations: Hand-editing config during MySQL-to-PostgreSQL moves; docker/ansible templates substituting the wrong type string; partially restored data/config.php.

Related errors


AI-assisted analysis of FreshRSS/FreshRSS@95842d81c1 (2026-08-23). Data as JSON: /api/errors/16c3ebb964eb6c19. Report an issue: GitHub.