{"record":{"id":"5be1cb049d876296","repo":"monicahq/monica","slug":"invalid-date-type","errorCode":null,"errorMessage":"Invalid date type","messagePattern":"Invalid date type","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":500,"severity":"error","filePath":"app/Domains/Contact/ManageContactImportantDates/Web/Controllers/ContactImportantDatesController.php","lineNumber":135,"sourceCode":"        $day = '';\n        $month = '';\n        $year = '';\n\n        switch ($request->input('choice')) {\n            case ContactImportantDate::TYPE_FULL_DATE:\n                $year = Carbon::parse($request->input('date'))->year;\n                $month = Carbon::parse($request->input('date'))->month;\n                $day = Carbon::parse($request->input('date'))->day;\n                break;\n            case ContactImportantDate::TYPE_MONTH_DAY:\n                $month = $request->input('month');\n                $day = $request->input('day');\n                break;\n            case ContactImportantDate::TYPE_YEAR:\n                $year = Carbon::now()->subYears($request->input('age'))->format('Y');\n                break;\n            default:\n                throw new \\InvalidArgumentException('Invalid date type');\n        }\n\n        return [$day, $month, $year];\n    }\n\n    public function destroy(Request $request, string $vaultId, string $contactId, string $dateId)\n    {\n        $data = [\n            'account_id' => Auth::user()->account_id,\n            'author_id' => Auth::id(),\n            'vault_id' => $vaultId,\n            'contact_id' => $contactId,\n            'contact_important_date_id' => $dateId,\n        ];\n\n        (new DestroyContactImportantDate)->execute($data);\n\n        // TODO - delete the reminder if it exists","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/monicahq/monica/blob/e08e91734170b6bbd582cb578532c3948196124e/app/Domains/Contact/ManageContactImportantDates/Web/Controllers/ContactImportantDatesController.php#L117-L153","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send one of the exact values: full_date, month_day, year","Whitelist the input in the form request: 'type' => ['required', Rule::in(array values)] so bad values 422 instead of 500","When introducing a new type, add the switch branch and a feature test in the same change"],"exampleFix":"// before\n$request->validate([\n    'type' => 'required|string', // accepts anything -> switch default -> 500\n]);\n\n// after\nuse Illuminate\\Validation\\Rule;\n\n$request->validate([\n    'type' => ['required', Rule::in([\n        ContactImportantDate::TYPE_FULL_DATE,\n        ContactImportantDate::TYPE_MONTH_DAY,\n        ContactImportantDate::TYPE_YEAR,\n    ])],\n]);","handlingStrategy":"validation","validationCode":"// Validate before calling: whitelist the date type against the model constants\nuse Illuminate\\Validation\\Rule;\n\n$validated = $request->validate([\n    'type' => ['required', 'string', Rule::in([\n        ContactImportantDate::TYPE_FULL_DATE,\n        ContactImportantDate::TYPE_MONTH_DAY,\n        ContactImportantDate::TYPE_YEAR,\n    ])],\n]);","typeGuard":"function isValidImportantDateType(string $type): bool\n{\n    return in_array($type, [\n        ContactImportantDate::TYPE_FULL_DATE,   // 'full_date'\n        ContactImportantDate::TYPE_MONTH_DAY,   // 'month_day'\n        ContactImportantDate::TYPE_YEAR,        // 'year'\n    ], true);\n}","tryCatchPattern":"try {\n    [$day, $month, $year] = $this->computeDateAttributes($request);\n} catch (\\InvalidArgumentException $e) {\n    throw ValidationException::withMessages([\n        'type' => 'Invalid date type. Use full_date, month_day or year.',\n    ]);\n}","preventionTips":["Never accept free-text type values from clients; whitelist with Rule::in","When adding a model TYPE_* constant, update every switch and add a test in the same change","Use the model constants everywhere instead of string literals","Treat an unhandled switch default as a defect and cover it with a unit test"],"tags":["monica","important-dates","enum","switch-default"],"backgroundTag":"invalid-enum-value","analyzedSha":"e08e91734170b6bbd582cb578532c3948196124e","analyzedAt":"2026-08-17T01:36:49.014Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}