monicahq/monica · error · InvalidArgumentException

Invalid date type

Error message

Invalid date type

What it means

ContactImportantDatesController computes (day, month, year) from the request by switching on the date type. Only the model constants TYPE_FULL_DATE ('full_date'), TYPE_MONTH_DAY ('month_day') and TYPE_YEAR ('year') have branches; every other value falls through to default and throws InvalidArgumentException, which surfaces as a 500.

Source

Thrown at app/Domains/Contact/ManageContactImportantDates/Web/Controllers/ContactImportantDatesController.php:135

        $day = '';
        $month = '';
        $year = '';

        switch ($request->input('choice')) {
            case ContactImportantDate::TYPE_FULL_DATE:
                $year = Carbon::parse($request->input('date'))->year;
                $month = Carbon::parse($request->input('date'))->month;
                $day = Carbon::parse($request->input('date'))->day;
                break;
            case ContactImportantDate::TYPE_MONTH_DAY:
                $month = $request->input('month');
                $day = $request->input('day');
                break;
            case ContactImportantDate::TYPE_YEAR:
                $year = Carbon::now()->subYears($request->input('age'))->format('Y');
                break;
            default:
                throw new \InvalidArgumentException('Invalid date type');
        }

        return [$day, $month, $year];
    }

    public function destroy(Request $request, string $vaultId, string $contactId, string $dateId)
    {
        $data = [
            'account_id' => Auth::user()->account_id,
            'author_id' => Auth::id(),
            'vault_id' => $vaultId,
            'contact_id' => $contactId,
            'contact_important_date_id' => $dateId,
        ];

        (new DestroyContactImportantDate)->execute($data);

        // TODO - delete the reminder if it exists

View on GitHub (pinned to e08e917341)

Solutions

  1. Send one of the exact values: full_date, month_day, year
  2. Whitelist the input in the form request: 'type' => ['required', Rule::in(array values)] so bad values 422 instead of 500
  3. When introducing a new type, add the switch branch and a feature test in the same change

Example fix

// before
$request->validate([
    'type' => 'required|string', // accepts anything -> switch default -> 500
]);

// after
use Illuminate\Validation\Rule;

$request->validate([
    'type' => ['required', Rule::in([
        ContactImportantDate::TYPE_FULL_DATE,
        ContactImportantDate::TYPE_MONTH_DAY,
        ContactImportantDate::TYPE_YEAR,
    ])],
]);
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling: whitelist the date type against the model constants
use Illuminate\Validation\Rule;

$validated = $request->validate([
    'type' => ['required', 'string', Rule::in([
        ContactImportantDate::TYPE_FULL_DATE,
        ContactImportantDate::TYPE_MONTH_DAY,
        ContactImportantDate::TYPE_YEAR,
    ])],
]);

Type guard

function isValidImportantDateType(string $type): bool
{
    return in_array($type, [
        ContactImportantDate::TYPE_FULL_DATE,   // 'full_date'
        ContactImportantDate::TYPE_MONTH_DAY,   // 'month_day'
        ContactImportantDate::TYPE_YEAR,        // 'year'
    ], true);
}

Try / catch

try {
    [$day, $month, $year] = $this->computeDateAttributes($request);
} catch (\InvalidArgumentException $e) {
    throw ValidationException::withMessages([
        'type' => 'Invalid date type. Use full_date, month_day or year.',
    ]);
}

Prevention

When it happens

Trigger: POST/PUT of a contact important date whose type is not 'full_date', 'month_day' or 'year' — e.g. sending 'birthdate' (a different model constant describing another concept), a localized label, or a new type constant added to the model without a matching controller branch.

Common situations: Adding a ContactImportantDate::TYPE_* constant without updating the switch, API consumers guessing type strings, or the frontend sending its display label instead of the stored value.

Related errors


AI-assisted analysis of monicahq/monica@e08e917341 (2026-08-17). Data as JSON: /api/errors/5be1cb049d876296. Report an issue: GitHub.