flarum/framework · error · ValidationFailed
The prefix may only contain characters and underscores.
Error message
The prefix may only contain characters and underscores.
What it means
ValidationFailed thrown by DatabaseConfig::validate when a non-empty table prefix contains characters outside Unicode letters, marks, numbers and underscores. The regex /^[\pL\pM\pN_]+$/u enforces identifier-safe prefixes so prefixed table names stay valid SQL.
Solutions
- Remove invalid characters — use only letters, digits and underscores, e.g. 'myapp_'.
- Replace hyphens/dots with underscores before constructing DatabaseConfig.
- Trim the prefix; if you do not need one, leave it empty (empty prefix is allowed).
Example fix
// before new DatabaseConfig(driver: 'mysql', host: 'db', port: 3306, database: 'app', prefix: 'my-app-'); // after new DatabaseConfig(driver: 'mysql', host: 'db', port: 3306, database: 'app', prefix: 'my_app_');
Defensive patterns
Strategy: validation
Validate before calling
$prefix = trim($rawPrefix);
if ($prefix !== '' && ! preg_match('/^[\\pL\\pM\\pN_]+$/u', $prefix)) {
$prefix = preg_replace('/[^\\pL\\pM\\pN_]/u', '_', $prefix);
}
$config = new DatabaseConfig(driver: $driver, host: $host, port: $port, database: $database, prefix: $prefix); Type guard
function isValidPrefix(string $prefix): bool {
return $prefix === '' || preg_match('/^[\\pL\\pM\\pN_]+$/u', $prefix) === 1;
} Try / catch
try {
$config = new DatabaseConfig(...$input);
} catch (ValidationFailed $e) {
if (str_contains($e->getMessage(), 'prefix may only')) {
$errors['prefix'] = 'Use only letters, numbers and underscores.';
}
} Prevention
- Sanitize prefix input server-side with preg_replace before validation.
- Add a client-side pattern attribute on the prefix input.
- Never derive prefixes from domains or URLs without normalization.
When it happens
Trigger: Setting prefix to a value with hyphens, dots, spaces, or other symbols, e.g. 'my-app-', 'app.prefix', 'flarum '.
Common situations: Users copying a prefix from a URL or domain (my-site.com_); hyphenated project names; whitespace from pasted input; trying to namespace tables with dots.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- The prefix should be no longer than $maxPrefix characters…
- Please specify a database driver.
- Please specify the hostname of your database server.
- Please provide a valid port number between 1 and 65535.
- Please specify the database name.
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/f00135cc1f8909e8.
Report an issue: GitHub.
Appendix: source
Thrown at framework/core/src/Install/DatabaseConfig.php:73
if (($this->port < 1 || $this->port > 65535) && in_array($this->driver, ['mysql', 'mariadb', 'pgsql'])) {
throw new ValidationFailed('Please provide a valid port number between 1 and 65535.');
}
if (empty($this->database)) {
throw new ValidationFailed('Please specify the database name.');
}
if (empty($this->schema) && $this->driver == 'pgsql') {
throw new ValidationFailed('Please specify the schema name.');
}
if (empty($this->username) && in_array($this->driver, ['mysql', 'mariadb', 'pgsql'])) {
throw new ValidationFailed('Please specify the username for accessing the database.');
}
if (! empty($this->prefix)) {
if (! preg_match('/^[\pL\pM\pN_]+$/u', $this->prefix)) {
throw new ValidationFailed('The prefix may only contain characters and underscores.');
}
$maxPrefix = DatabaseRequirements::maxTablePrefixLength($this->driver);
if ($maxPrefix !== null && strlen($this->prefix) > $maxPrefix) {
throw new ValidationFailed("The prefix should be no longer than $maxPrefix characters on $this->driver.");
}
}
}
public function prepare(Paths $paths): void
{
if ($this->driver === 'sqlite' && ! file_exists($this->database)) {
$this->database = str_replace('.sqlite', '', $this->database).'.sqlite';
touch($paths->base.'/'.$this->database);
}
}
View on GitHub (pinned to 4b939f6853)