{"record":{"id":"82fbc33df0ac7926","repo":"bytebase/bytebase","slug":"failed-to-parse-time-v-error-v-82fbc3","errorCode":null,"errorMessage":"failed to parse time %v, error: %v","messagePattern":"failed to parse time (.+?), error: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/store/audit_log.go","lineNumber":233,"sourceCode":"\t\t\t\t}\n\t\t\t\treturn qb.Q().Space(\"(?)\", q), nil\n\t\t\tcase celoperators.Equals:\n\t\t\t\tvariable, rawValue := getVariableAndValueFromExpr(expr)\n\t\t\t\treturn auditLogEqualsFilter(variable, rawValue)\n\n\t\t\tcase celoperators.GreaterEquals, celoperators.LessEquals:\n\t\t\t\tvariable, rawValue := getVariableAndValueFromExpr(expr)\n\t\t\t\tvalue, ok := rawValue.(string)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, errors.Errorf(\"expect string, got %T, hint: filter literals should be string\", rawValue)\n\t\t\t\t}\n\t\t\t\tif variable != \"create_time\" {\n\t\t\t\t\treturn nil, errors.Errorf(`\">=\" and \"<=\" are only supported for \"create_time\"`)\n\t\t\t\t}\n\n\t\t\t\tt, err := time.Parse(time.RFC3339, value)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, errors.Errorf(\"failed to parse time %v, error: %v\", value, err)\n\t\t\t\t}\n\t\t\t\tif functionName == celoperators.GreaterEquals {\n\t\t\t\t\treturn qb.Q().Space(\"created_at >= ?\", t), nil\n\t\t\t\t}\n\t\t\t\treturn qb.Q().Space(\"created_at <= ?\", t), nil\n\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.Errorf(\"unexpected function %v\", functionName)\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn nil, errors.Errorf(\"unexpected expr kind %v\", expr.Kind())\n\t\t}\n\t}\n\n\tq, err := getFilter(ast.NativeRep().Expr())\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/store/audit_log.go#L215-L251","documentation":"After confirming the >=/<= filter targets create_time and its value is a string, the code parses it with time.Parse(time.RFC3339, ...). A string that is not a valid RFC3339 timestamp makes time.Parse fail and this wrapped error reports both the offending value and the underlying parse error.","triggerScenarios":"create_time values like \"2024-01-01\" (date only), \"2024/01/01 00:00:00\", epoch \"1700000000\", or timestamps missing timezone offset.","commonSituations":"Clients sending local date formats; JavaScript Date.toString() output; epoch milliseconds; forgetting the Z or +00:00 offset.","solutions":["Send a full RFC3339 timestamp: 2024-01-01T00:00:00Z.","Ensure the timezone offset is present (Z or ±hh:mm).","In Go, format with time.RFC3339 or time.RFC3339Nano before embedding in the filter.","In JS, use date.toISOString() which is RFC3339-compliant."],"exampleFix":"// before\nfilter := \"create_time >= \\\"2024-01-01\\\"\"            // date only, parse fails\n// after\nfilter := \"create_time >= \\\"2024-01-01T00:00:00Z\\\"\"  // RFC3339","handlingStrategy":"validation","validationCode":"const RFC3339 = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\nif (!RFC3339.test(ts)) throw new Error(`create_time must be RFC3339, got ${ts}`);","typeGuard":null,"tryCatchPattern":"try { return await searchAuditLogs({ filter }); } catch (e) { if (String(e).includes(\"failed to parse time\")) { throw new Error(`Format timestamps with toISOString()/RFC3339: ${ts}`); } throw e; }","preventionTips":["Validate timestamps with an RFC3339 regex before embedding","Use date.toISOString() (JS) or t.Format(time.RFC3339) (Go)","Never send date-only strings or epoch values"],"tags":["timestamp","filter","date-parsing"],"backgroundTag":"invalid-date-format","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}