NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Two independent settings decide the key types in the schema. Both accept bigint (the default), uuid or ulid; anything else throws InvalidConfigurationException naming the key:

SettingDirectionWhat it types
primary_key_typeInbound — what other packages point atThe id of messaging_threads, messaging_messages and messaging_participants, plus thread_id, parent_message_id, last_read_message_id and last_message_id.
key_typeOutbound — what this package points atThe sender_id and participant_id morph columns, which must match your User, Company or other participant models.
MESSAGES_KEY_TYPE=uuid             # User uses HasUuids
# MESSAGES_PRIMARY_KEY_TYPE stays bigint

Both are read when the migrations run, so choose them before you publish and migrate. Changing them afterwards is a data migration, not a config change.

key_type must match your models

Leave key_type at bigint with uuid users and PostgreSQL rejects the very first conversation:

SQLSTATE[22P02]: invalid input syntax for type bigint: "01a0fc2b-4518-722a-8e92-50589b45ba2a"

Every model that sends or participates shares the sender_id and participant_id columns, so they must all use that one key type — a bigint User and a uuid Company cannot both take part.

Why primary_key_type defaults to bigint

A thread or a message is a thing other packages point at polymorphically, and a Laravel morph column ($table->morphs(…)) is an unsigned bigint. On a strict engine such as PostgreSQL, a uuid id will not go into one — the same error as above.

SQLite will not warn you about either mismatch — its type affinity silently stores the string in an integer column, so a green SQLite suite proves nothing here.

One key type per application

If you set MESSAGES_PRIMARY_KEY_TYPE=uuid, the models on the other end of your polymorphic relations need to be uuid-keyed too, and the packages owning those columns need to agree. A mixed application — a uuid Thread and a bigint Post pointed at by the same morph column — is not supported by this package, by Laravel’s own morphs()/uuidMorphs() split, or by anything else.

key_type is the other axis: a bigint-keyed messaging install with uuid users is an ordinary application — set MESSAGES_KEY_TYPE=uuid and leave MESSAGES_PRIMARY_KEY_TYPE at bigint, as in the example above.

Generated keys

On uuid and ulid the models mint their own ids — UUIDv7 or ULID — both time-ordered, so newest-first ordering and the inbox’s latest-message lookup stay deterministic on every key setting. On bigint the database assigns ids as usual.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.