{"record":{"id":"510fc1a96a06351f","repo":"mongodb/laravel-mongodb","slug":"invalid-time-format-expected-hh-mm-ss-hh-mm-or-hh-got-s","errorCode":null,"errorMessage":"Invalid time format, expected HH:MM:SS, HH:MM or HH, got \"%s\"","messagePattern":"Invalid time format, expected HH:MM:SS, HH:MM or HH, got \"(.+?)\"","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Query/Builder.php","lineNumber":1682,"sourceCode":"\n    protected function compileWhereYear(array $where): array\n    {\n        return [\n            '$expr' => [\n                '$' . $where['operator'] => [\n                    [\n                        '$year' => '$' . $where['column'],\n                    ],\n                    (int) $where['value'],\n                ],\n            ],\n        ];\n    }\n\n    protected function compileWhereTime(array $where): array\n    {\n        if (! is_string($where['value']) || ! preg_match('/^[0-2][0-9](:[0-6][0-9](:[0-6][0-9])?)?$/', $where['value'], $matches)) {\n            throw new InvalidArgumentException(sprintf('Invalid time format, expected HH:MM:SS, HH:MM or HH, got \"%s\"', is_string($where['value']) ? $where['value'] : get_debug_type($where['value'])));\n        }\n\n        $format = match (count($matches)) {\n            1 => '%H',\n            2 => '%H:%M',\n            3 => '%H:%M:%S',\n        };\n\n        return [\n            '$expr' => [\n                '$' . $where['operator'] => [\n                    [\n                        '$dateToString' => ['date' => '$' . $where['column'], 'format' => $format],\n                    ],\n                    $where['value'],\n                ],\n            ],\n        ];","sourceCodeStart":1664,"sourceCodeEnd":1700,"githubUrl":"https://github.com/mongodb/laravel-mongodb/blob/0634653039468ceb0268a69192bdac64469ed043/src/Query/Builder.php#L1664-L1700","documentation":"compileWhereTime() accepts only string times matching HH, HH:MM or HH:MM:SS (hours 00-29 syntactically) so it can map them to a $dateToString format for time comparison. Anything else — non-strings or malformed strings — throws InvalidArgumentException.","triggerScenarios":"->whereTime('created_at', '>=', '9:30') (single-digit hour); ->whereTime('t', '=', '09:30:00.123') (fractional seconds); ->whereTime('t', '=', 930) (int); Carbon/DateTime objects passed instead of strings.","commonSituations":"Passing time values from user input or DB numeric columns; passing DateTimeInterface instances expecting automatic conversion; locale-formatted times like '9:30 AM'.","solutions":["Format the value first: $dt->format('H:i:s') before passing to whereTime().","Zero-pad hours: '09:30' not '9:30'.","Pass exactly one of the supported shapes: 'HH', 'HH:MM', 'HH:MM:SS'.","For non-string values, convert with sprintf('%02d:%02d:%02d', $h, $m, $s) or use ->whereRaw / date aggregation instead."],"exampleFix":"// before\n$query->whereTime('created_at', '>=', '9:30 AM');\n// after\n$query->whereTime('created_at', '>=', '09:30');","handlingStrategy":"validation","validationCode":"function normalizeTime(mixed $t): string {\n    if ($t instanceof \\DateTimeInterface) return $t->format('H:i:s');\n    if (is_string($t) && preg_match('/^([01]?\\d|2\\d):([0-5]\\d)(?::([0-5]\\d))?$/', $t, $m)) {\n        return sprintf('%02d:%s:%s', $m[1], $m[2], $m[3] ?? '00');\n    }\n    throw new InvalidArgumentException('Time must be HH, HH:MM or HH:MM:SS');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize all times through a format('H:i:s') helper.","Zero-pad hours and drop AM/PM and fractional seconds.","Pass DateTimeInterface through ->format() before whereTime()."],"tags":["php","laravel-mongodb","date-time"],"backgroundTag":"invalid-date-format","analyzedSha":"0634653039468ceb0268a69192bdac64469ed043","analyzedAt":"2026-09-15T02:56:37.067Z","contentChangedAt":"2026-09-15T02:56:37.067Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}