flarum/framework · warning · ValidationException
validation. (translated message for )
Error message
validation.<error> (translated message for <filename>)
What it means
AbstractImageValidator::raise converts a failed file validation rule (file required, disallowed mime type, or size over limit) into a translated 'validation.<error>' message and throws ValidationException keyed by the upload's filename. It is the base class for Flarum's avatar/logo upload validators.
Solutions
- Upload a file whose type is one of the allowed image mimes (e.g. png, jpeg, webp) and resize it under the max size.
- Raise the limits by overriding getMaxSize()/getAllowedMimes() in a subclass or extension before calling assertValid.
- Handle the ValidationException in the controller/response to show the per-field translated errors to the user instead of surfacing a 500.
Example fix
// before: uploading avatar.pdf
// after: client-side guard before POST
const file = input.files[0];
if (!/^image\/(png|jpe?g|webp)$/.test(file.type) || file.size > 2 * 1024 * 1024) {
alert('Please choose an image under 2MB');
return;
} Defensive patterns
Strategy: validation
Validate before calling
// client-side pre-check before upload
const allowed = ['image/png','image/jpeg','image/webp'];
if (!allowed.includes(file.type) || file.size > 2 * 1024 * 1024) {
alert('Only PNG/JPEG/WebP under 2MB allowed');
} Type guard
const isUploadableImage = (f) => f instanceof File && /^image\//.test(f.type) && f.size > 0 && f.size <= 2 * 1024 * 1024;
Try / catch
try {
$validator->assertValid(['file' => $uploadedFile]);
} catch (ValidationException $e) {
return response()->json(['errors' => $e->errors()], 422);
} Prevention
- Check allowed mime types and size limits before every upload call.
- Resize/compress images client-side when over the limit.
- Map the per-filename error keys to the correct form fields when displaying.
When it happens
Trigger: Uploading a file through endpoints validated by subclasses (e.g. UploadAvatarController, UploadLogoController) when: no file is provided, the file's mime type isn't in the allowed list (jpg/png/bmp/svg/webp variants), or the file exceeds getMaxSize() (default 2048 KiB).
Common situations: Users uploading PDFs or videos as avatars; profile pictures larger than the configured size limit; empty multipart uploads from broken clients.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ValidationException (messages from password validator)
- core.admin.appearance.custom_styles_cannot_use_less_features
- custom_less
- ValidationException (messages from validator)
- Both text and html views must be provided to send an email…
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/4274b7e05ca7b19e.
Report an issue: GitHub.
Appendix: source
Thrown at framework/core/src/Foundation/AbstractImageValidator.php:135
if ($size === null || $size / 1024 > $maxSize) {
$this->raise('max.file', [':max' => $maxSize], 'max');
}
}
protected function raise(string $error, array $parameters = [], ?string $rule = null): void
{
// When we switched to intl ICU message format, the translation parameters
// have become required to be in the format `{param}`.
// Therefore, we cannot use the translator to replace the string params.
// We use the laravel validator to make the replacements instead.
$message = $this->laravelValidator->makeReplacements(
$this->translator->trans("validation.$error"),
$this->filename,
$rule ?? $error,
array_values($parameters)
);
throw new ValidationException([$this->filename => $message]);
}
public function getMaxSize(): int
{
return 2048;
}
/**
* The maximum number of pixels (width * height) allowed in an uploaded
* image. This bounds the memory a single decode can allocate, guarding
* against decompression-bomb uploads that declare huge dimensions in a
* tiny file. ~24 megapixels comfortably covers legitimate photos while
* rejecting pathological dimensions.
*/
public function getMaxResolution(): int
{
return 24_000_000;
}View on GitHub (pinned to 4b939f6853)