laravel/framework · error · InvalidArgumentException
Morph key type must be 'int', 'uuid', or 'ulid'.
Error message
Morph key type must be 'int', 'uuid', or 'ulid'.
What it means
Schema\Builder::defaultMorphKeyType is a static method that sets the global default morph key type for all migrations and polymorphic relationships. It validates that the type is one of 'int', 'uuid', or 'ulid' and throws InvalidArgumentException otherwise. This type determines the column definition for morphs()/nullableMorphs() and the key type stored in polymorphic morph_type columns.
Solutions
- Pass one of the three allowed values: Schema::defaultMorphKeyType('int'), 'uuid', or 'ulid'
- Use the convenience methods: Schema::morphUsingUuids() or Schema::morphUsingUlids() instead of calling defaultMorphKeyType directly
- If you need a custom key type, you cannot use defaultMorphKeyType — override morphs() calls individually with custom column definitions
Example fix
// before — invalid type throws
Schema::defaultMorphKeyType('string');
// after — use a supported type
Schema::defaultMorphKeyType('uuid');
// or use the convenience method
Schema::morphUsingUuids(); Defensive patterns
Strategy: validation
Validate before calling
$validTypes = ['int', 'uuid', 'ulid'];
if (in_array($type, $validTypes, true)) {
Schema::defaultMorphKeyType($type);
} else {
throw new \InvalidArgumentException("Invalid morph key type: {$type}. Must be one of: " . implode(', ', $validTypes));
} Type guard
function isValidMorphKeyType(string $type): bool {
return in_array($type, ['int', 'uuid', 'ulid'], true);
} Prevention
- Use the convenience methods Schema::morphUsingUuids() or Schema::morphUsingUlids() instead of calling defaultMorphKeyType directly
- Hard-code one of the three allowed string literals — do not pass dynamic/user input
- Set morph key type once in AppServiceProvider::boot() and leave it unchanged for the application lifetime
- Document the morph key type in project setup docs so all developers use the same type
When it happens
Trigger: Calling Schema::defaultMorphKeyType('string'), Schema::defaultMorphKeyType('bigint'), or any value other than 'int', 'uuid', or 'ulid'. Typically called in AppServiceProvider::boot() or a migration file.
Common situations: Developer passes a type name that seems valid but is not in the allowed set (e.g., 'bigIncrements', 'string', 'guid'). Typo in the type string. Passing a variable that contains an unexpected value.
Related errors
- Collection given to whereMorphedTo method may not be empty.
- Collection given to whereNotMorphedTo method may not be…
- Add fillable property
- Collection given to whereAttachedTo method may not be empty.
- Collection given to whereBelongsTo method may not be empty.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/5e23800c479f7315.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Schema/Builder.php:99
* Set the default time precision for migrations.
*/
public static function defaultTimePrecision(?int $precision): void
{
static::$defaultTimePrecision = $precision;
}
/**
* Set the default morph key type for migrations.
*
* @param string $type
* @return void
*
* @throws \InvalidArgumentException
*/
public static function defaultMorphKeyType(string $type)
{
if (! in_array($type, ['int', 'uuid', 'ulid'])) {
throw new InvalidArgumentException("Morph key type must be 'int', 'uuid', or 'ulid'.");
}
static::$defaultMorphKeyType = $type;
}
/**
* Set the default morph key type for migrations to UUIDs.
*
* @return void
*/
public static function morphUsingUuids()
{
static::defaultMorphKeyType('uuid');
}
/**
* Set the default morph key type for migrations to ULIDs.
*View on GitHub (pinned to e0f6eb3518)