flarum/framework · error · ValidationException
str_replace(':attribute', 'users'…
Error message
str_replace(':attribute', 'users', $this->translator->trans('validation.required')) What it means
When creating a dialog message without dialog_id, the resource checks the 'users' attribute for valid recipient ids (excluding the actor); if the resulting list is empty it throws a ValidationException on the 'users' field with the translated 'required' message. The odd message string shown is the raw translation call that generates the text.
Solutions
- Include attributes.users with at least one valid user id other than the sender.
- Provide dialog_id to send into an existing dialog instead of creating a new one.
- Ensure ids in the users array are integers/strings of existing users and not empty values.
- Verify the frontend sends the recipients under data.attributes.users.
Example fix
// before
{ "attributes": { "content": "hi", "users": [] } }
// after
{ "attributes": { "content": "hi", "users": [{ "id": 7 }] } } Defensive patterns
Strategy: validation
Validate before calling
const users = (attrs.users ?? []).map(u => u.id).filter(id => id && id !== currentUserId); if (!attrs.dialog_id && users.length === 0) { /* require recipients before submit */ } Try / catch
try { await store.createRecord('dialog-messages', payload).save(); } catch (e) { if (e.errors?.users) show('Select at least one recipient'); } Prevention
- Require recipient selection in the UI when no dialog_id
- Filter out the sender and empty ids client-side
- Prefer dialog_id for existing conversations
When it happens
Trigger: POST /api/dialog-messages without dialog_id and with attributes.users missing, empty, containing only null/blank ids, or containing only the sender's own id.
Common situations: Frontend not collecting recipients before send; user attempts to message only themselves; stale UI state after recipients were removed.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- flarum-akismet.admin.akismet_settings.invalid_api_key_messag…
- Incorrect password
- Invalid erasure mode: $mode
- You can only use page[near] with filter[dialog] and the…
- ValidationException (messages from password validator)
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/fead7aaa98a489f0.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/messages/src/Api/Resource/DialogMessageResource.php:239
/**
* @inheritDoc
*/
public function creating(object $model, OriginalContext $context): ?object
{
$model->user_id = $context->getActor()->id;
$data = $context->body()['data'] ?? [];
$this->events->dispatch(
new DialogMessage\Event\Creating($model, $data)
);
if (! $model->dialog_id) {
$context->getActor()->assertCan('sendAnyMessage');
$users = array_filter(Arr::pluck($data['attributes']['users'] ?? [], 'id'), fn (mixed $id) => $id && $id != $model->user_id);
if (empty($users)) {
throw new ValidationException([
'users' => str_replace(':attribute', 'users', $this->translator->trans('validation.required')),
]);
}
$dialog = Dialog::for($model, $users);
$model->dialog()->associate($dialog);
$users[] = $model->user_id;
$dialog->users()->syncWithPivotValues(array_unique($users), [
'joined_at' => Carbon::now(),
]);
}
return parent::creating($model, $context);
}
View on GitHub (pinned to 4b939f6853)