{"record":{"id":"8d2219a8421a01d7","repo":"vitessio/vitess","slug":"couldn-t-parse-build-timestamp-q-v","errorCode":null,"errorMessage":"Couldn't parse build timestamp %q: %v","messagePattern":"Couldn't parse build timestamp %q: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/servenv/buildinfo.go","lineNumber":159,"sourceCode":"// parseBuildTime resolves the build timestamp into the pretty string and Unix\n// timestamp used by AppVersion. An explicitly injected BUILD_TIME (via ldflags,\n// in time.UnixDate format) takes precedence so that package/tarball builds can set\n// it deliberately; otherwise it uses the VCS-stamped commit time (RFC3339), which\n// the Go toolchain records for normal git builds. An unparseable override is logged\n// and ignored so it falls through to the VCS time. It returns zero values when no\n// usable timestamp is available.\nfunc parseBuildTime(override, vcsTime string) (pretty string, unix int64) {\n\tif override != \"\" {\n\t\tt, err := time.Parse(time.UnixDate, override)\n\t\tif err == nil {\n\t\t\treturn override, t.Unix()\n\t\t}\n\t\tlog.Warn(\"Ignoring unparseable BUILD_TIME override\", slog.String(\"build_time\", override), slog.Any(\"error\", err))\n\t}\n\tif vcsTime != \"\" {\n\t\tt, err := time.Parse(time.RFC3339, vcsTime)\n\t\tif err != nil {\n\t\t\tpanic(fmt.Sprintf(\"Couldn't parse build timestamp %q: %v\", vcsTime, err))\n\t\t}\n\t\treturn vcsTime, t.Unix()\n\t}\n\treturn \"\", 0\n}\n\nfunc init() {\n\trevision, revisionTime, modified := readVCSInfo()\n\tgitRev := resolveGitRev(revision, modified, buildGitRev)\n\tbuildTimePretty, buildTime := parseBuildTime(buildTimeOverride, revisionTime)\n\n\tbuildNumber, err := strconv.ParseInt(buildNumberStr, 10, 64)\n\tif err != nil {\n\t\tbuildNumber = 0\n\t}\n\n\tAppVersion = versionInfo{\n\t\tbuildHost:       buildHost,","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/servenv/buildinfo.go#L141-L177","documentation":"parseBuildTime parses the build timestamp (from VCS stamping) with time.RFC3339. An unparseable BUILD_TIME override is only warned about, but an unparseable vcs time value is a build-injection bug — the value embedded at link time is malformed — so it panics at init.","triggerScenarios":"Building/linking vitess with -ldflags that inject a vcs.buildTime / BUILD_TIME value not in RFC3339 format (e.g. '2024-01-02 15:04:05' instead of '2024-01-02T15:04:05Z'), causing panic at package init.","commonSituations":"Custom build scripts that format the git commit date incorrectly; overriding BUILD_TIME via ldflags with a locale-formatted date string; CI scripts using 'git log --format=%cd' with a custom date format.","solutions":["Fix the build script to emit RFC3339 format, e.g. date -u +'%Y-%m-%dT%H:%M:%SZ' or git log -1 --format=%cI","Rebuild without the malformed timestamp override so the default (empty, 0) is used","Test the exact string with `date -d` / a Go time.Parse(time.RFC3339, ...) before injecting"],"exampleFix":"// before\n-BUILD_TIME=$(git log -1 --format=%cd --date=format:'%Y-%m-%d %H:%M:%S')\n// after\nBUILD_TIME=$(git log -1 --format=%cI)","handlingStrategy":"validation","validationCode":"# validate before injecting in build scripts\n[[ \"$BUILD_TIME\" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ ]] || { echo \"BUILD_TIME must be RFC3339\"; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use git log --format=%cI or date -u +'%Y-%m-%dT%H:%M:%SZ' for timestamps","Test the ldflags string parses as RFC3339 in CI","Prefer not overriding BUILD_TIME unless required"],"tags":["go","panic","build","ldflags","time-parsing"],"backgroundTag":"invalid-timestamp-format","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}