{"record":{"id":"2d3ca9aeb45e043a","repo":"golang/go","slug":"does-not-match-version-control-timestamp-expected","errorCode":null,"errorMessage":"does not match version-control timestamp (expected %s)","messagePattern":"does not match version-control timestamp \\(expected (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/coderepo.go","lineNumber":710,"sourceCode":"\t\treturn err\n\t}\n\tif rev != info.Short {\n\t\tswitch {\n\t\tcase strings.HasPrefix(rev, info.Short):\n\t\t\treturn fmt.Errorf(\"revision is longer than canonical (expected %s)\", info.Short)\n\t\tcase strings.HasPrefix(info.Short, rev):\n\t\t\treturn fmt.Errorf(\"revision is shorter than canonical (expected %s)\", info.Short)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"does not match short name of revision (expected %s)\", info.Short)\n\t\t}\n\t}\n\n\tt, err := module.PseudoVersionTime(version)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !t.Equal(info.Time.Truncate(time.Second)) {\n\t\treturn fmt.Errorf(\"does not match version-control timestamp (expected %s)\", info.Time.UTC().Format(module.PseudoVersionTimestampFormat))\n\t}\n\n\ttagPrefix := \"\"\n\tif r.codeDir != \"\" {\n\t\ttagPrefix = r.codeDir + \"/\"\n\t}\n\n\t// A pseudo-version should have a precedence just above its parent revisions,\n\t// and no higher. Otherwise, it would be possible for library authors to \"pin\"\n\t// dependency versions (and bypass the usual minimum version selection) by\n\t// naming an extremely high pseudo-version rather than an accurate one.\n\t//\n\t// Moreover, if we allow a pseudo-version to use any arbitrary pre-release\n\t// tag, we end up with infinitely many possible names for each commit. Each\n\t// name consumes resources in the module cache and proxies, so we want to\n\t// restrict them to a finite set under control of the module author.\n\t//\n\t// We address both of these issues by requiring the tag upon which the","sourceCodeStart":692,"sourceCodeEnd":728,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/coderepo.go#L692-L728","documentation":"validatePseudoVersion (coderepo.go:705-711) parses the UTC timestamp encoded in the pseudo-version and compares it (to the second) against info.Time from the VCS. A mismatch means the timestamp in the version string lies about when the commit was made. The timestamp is load-bearing for version ordering, so a wrong timestamp would let authors artificially inflate precedence — hence the strict check.","triggerScenarios":"Hand-building a pseudo-version with an invented or rounded timestamp; timezone mishandling when constructing the UTC timestamp; a VCS reports commit time in a non-UTC zone and the constructor didn't convert.","commonSituations":"Generating pseudo-versions with `date -u` but wrong format string; rebases that change commit timestamps; pseudo-versions built before the toolchain enforced the canonical timestamp format.","solutions":["Let the toolchain derive the pseudo-version: `go get <module>@<commit>` — it reads the commit time from the VCS and formats it correctly.","If constructing manually, use `git log -1 --format=%cI <commit>` to get the UTC timestamp and the format `YYYYMMDDHHMMSS`.","After upstream rebases that alter commit times, refresh affected pseudo-versions."],"exampleFix":"// before (timestamp does not match commit)\nrequire example.com/m v0.0.0-20231231235959-e3702bed3d42\n\n// after (use the commit's actual UTC time)\nrequire example.com/m v0.0.0-20240101120000-e3702bed3d42","handlingStrategy":"validation","validationCode":"// Ensure the timestamp matches the commit's UTC time.\n// bash:\n//   ts=$(git log -1 --format=%cI <commit> | date -u +%Y%m%d%H%M%S)\n//   # the pseudo-version must contain this exact timestamp\n//\n// Go:\npackage main\nimport (\"time\"; \"golang.org/x/mod/module\")\nfunc validateTs(pseudo string, commitTime time.Time) error {\n    t, err := module.PseudoVersionTime(pseudo)\n    if err != nil { return err }\n    if !t.Equal(commitTime.Truncate(time.Second)) {\n        return fmt.Errorf(\"timestamp mismatch: pseudo=%s commit=%s\", t, commitTime)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always derive pseudo-versions through the toolchain, never by hand.","Use `%cI` (strict ISO 8601) and convert to UTC before formatting.","After rebases that change commit times, refresh pseudo-versions."],"tags":["go-modules","pseudo-version","timestamp","validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}