{"record":{"id":"7c7b3eb5d6d353cc","repo":"tailscale/tailscale","slug":"could-not-parse-otherdate-q-w","errorCode":null,"errorMessage":"Could not parse otherDate %q: %w","messagePattern":"Could not parse otherDate %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"version/mkversion/mkversion.go","lineNumber":286,"sourceCode":"\t\t// Technically we could populate these fields without the otherHash, but\n\t\t// these version numbers only make sense when building from Tailscale's\n\t\t// proprietary repo, so don't clutter open-source-only outputs with\n\t\t// them.\n\t\tret.Xcode = fmt.Sprintf(\"%d.%d.%d\", v.major+100, v.minor, v.patch)\n\t\tret.Winres = fmt.Sprintf(\"%d,%d,%d,0\", v.major, v.minor, v.patch)\n\t\tret.MSIProductCodes = makeMSIProductCodes(v, track)\n\t}\n\tif v.otherDate != \"\" {\n\t\tret.OtherDate = fmt.Sprintf(\"%s\", v.otherDate)\n\n\t\t// Generate a monotonically increasing version number for the macOS app, as\n\t\t// expected by Apple. We use the date so that it's always increasing (if we\n\t\t// based it on the actual version number we'd run into issues when doing\n\t\t// cherrypick stable builds from a release branch after unstable builds from\n\t\t// HEAD).\n\t\totherSec, err := strconv.ParseInt(v.otherDate, 10, 64)\n\t\tif err != nil {\n\t\t\treturn VersionInfo{}, fmt.Errorf(\"Could not parse otherDate %q: %w\", v.otherDate, err)\n\t\t}\n\t\totherTime := time.Unix(otherSec, 0).UTC()\n\t\t// We started to need to do this in 2023, and the last Apple-generated\n\t\t// incrementing build number was 273. To avoid using up the space, we\n\t\t// use <year - 1750> as the major version (thus 273.*, 274.* in 2024, etc.),\n\t\t// so that we're still in the same range. This way if Apple goes back to\n\t\t// auto-incrementing the number for us, we can go back to it with\n\t\t// reasonable-looking numbers.\n\t\t// In May 2024, a build with version number 275 was uploaded to the App Store\n\t\t// by mistake, causing any 274.* build to be rejected. To address this, +1 was\n\t\t// added, causing all builds to use the 275.* prefix.\n\t\tret.XcodeMacOS = fmt.Sprintf(\"%d.%d.%d\", otherTime.Year()-1750+1, otherTime.YearDay(), otherTime.Hour()*60*60+otherTime.Minute()*60+otherTime.Second())\n\t}\n\n\treturn ret, nil\n}\n\n// makeMSIProductCodes produces per-architecture v5 UUIDs derived from the pkgs","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/version/mkversion/mkversion.go#L268-L304","documentation":"For importer repos, otherDate is the commit timestamp captured as `git log --format=%ct` output and later parsed with strconv.ParseInt to build Apple's monotonically increasing XcodeMacOS number (275.DAY.SECONDS style). This error means the captured string was not a base-10 integer - git emitted empty or unexpected stdout for the timestamp query.","triggerScenarios":"A git wrapper/alias/shim in PATH that prints extra text to stdout, an exotic or broken git build, or (rarely) output that is empty because HEAD resolution produced nothing on stdout while succeeding.","commonSituations":"Corporate machines with git wrappers; CI images with unusual git builds; environments where GIT_* env vars alter log output.","solutions":["Run `git log -n1 --format=%ct HEAD` in your repo and inspect stdout for anything non-numeric","Remove git aliases/wrappers or env like GIT_PAGER/GIT_TRACE that could pollute stdout","Upgrade/normalize git in the build environment to an official build"],"exampleFix":"# before\n$ git log -n1 --format=%ct HEAD\nwarning: using slow parser  # wrapper noise -> Could not parse otherDate\n\n# after (plain git)\n$ git log -n1 --format=%ct HEAD\n1755500000","handlingStrategy":"try-catch","validationCode":"// Sanity-check that git emits a clean unix timestamp in this repo.\nout, err := exec.Command(\"git\", \"-C\", dir, \"log\", \"-n1\", \"--format=%ct\", \"HEAD\").Output()\nif err != nil {\n\treturn err\n}\nif _, err := strconv.ParseInt(strings.TrimSpace(string(out)), 10, 64); err != nil {\n\treturn fmt.Errorf(\"git wrapper pollutes stdout; fix git environment: %w\", err)\n}\nv, err := mkversion.InfoFrom(dir)","typeGuard":"func isOtherDateParseError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"Could not parse otherDate\")\n}","tryCatchPattern":"v, err := mkversion.InfoFrom(dir)\nif err != nil {\n\tif isOtherDateParseError(err) {\n\t\t// Environment problem (git wrapper), not a code problem.\n\t\tlog.Printf(\"unexpected git output; run `git log -n1 --format=%ct HEAD` to inspect: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Keep the build environment free of git aliases, wrappers, and hooks that write to stdout","Use an official git build in CI"],"tags":["git","parsing","mkversion","rare"],"backgroundTag":"unexpected-command-output","analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}