{"record":{"id":"3b68fbe7bb41aa4a","repo":"golang/go","slug":"invalid-version-q","errorCode":null,"errorMessage":"invalid version: %q","messagePattern":"invalid version: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modcmd/edit.go","lineNumber":397,"sourceCode":"\t\tpath, version = strings.TrimSpace(before), strings.TrimSpace(after)\n\t}\n\tif err := module.CheckImportPath(path); err != nil {\n\t\treturn path, version, fmt.Errorf(\"invalid %s path: %v\", adj, err)\n\t}\n\tif path != arg && !allowedVersionArg(version) {\n\t\treturn path, version, fmt.Errorf(\"invalid %s version: %q\", adj, version)\n\t}\n\treturn path, version, nil\n}\n\n// parseVersionInterval parses a single version like \"v1.2.3\" or a closed\n// interval like \"[v1.2.3,v1.4.5]\". Note that a single version has the same\n// representation as an interval with equal upper and lower bounds: both\n// Low and High are set.\nfunc parseVersionInterval(arg string) (modfile.VersionInterval, error) {\n\tif !strings.HasPrefix(arg, \"[\") {\n\t\tif !allowedVersionArg(arg) {\n\t\t\treturn modfile.VersionInterval{}, fmt.Errorf(\"invalid version: %q\", arg)\n\t\t}\n\t\treturn modfile.VersionInterval{Low: arg, High: arg}, nil\n\t}\n\tif !strings.HasSuffix(arg, \"]\") {\n\t\treturn modfile.VersionInterval{}, fmt.Errorf(\"invalid version interval: %q\", arg)\n\t}\n\ts := arg[1 : len(arg)-1]\n\tbefore, after, found := strings.Cut(s, \",\")\n\tif !found {\n\t\treturn modfile.VersionInterval{}, fmt.Errorf(\"invalid version interval: %q\", arg)\n\t}\n\tlow := strings.TrimSpace(before)\n\thigh := strings.TrimSpace(after)\n\tif !allowedVersionArg(low) || !allowedVersionArg(high) {\n\t\treturn modfile.VersionInterval{}, fmt.Errorf(\"invalid version interval: %q\", arg)\n\t}\n\treturn modfile.VersionInterval{Low: low, High: high}, nil\n}","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modcmd/edit.go#L379-L415","documentation":"`go mod edit` interval parsing (`parseVersionInterval`): the input is not bracket-delimited, so it is treated as a single version and fails `allowedVersionArg`. Used by flags that accept version intervals (e.g. `-exclude=[low,high]`). A single bare token must still be a valid version string.","triggerScenarios":"`go mod edit -exclude 'foo@1.0.0'` (missing `v`, non-bracketed); `go mod edit -droprequire='foo@random'`; passing a non-semver token where a single version is expected.","commonSituations":"Same family as 918 but within interval/single-version flags; forgetting `v` prefix; using branch or arbitrary strings.","solutions":["Supply a canonical semver token with the `v` prefix (`v1.2.3`).","For an interval, use the `[v1.0.0,v2.0.0]` bracket form.","Use `latest` only where the flag allows it — `parseVersionInterval` requires concrete versions."],"exampleFix":"// before\ngo mod edit -exclude='foo@[1.0.0,2.0.0]'\n\n// after\ngo mod edit -exclude='foo@[v1.0.0,v2.0.0]'","handlingStrategy":"validation","validationCode":"// Validate a version or [low,high] interval before `go mod edit`.\nfunc validVersionOrInterval(s string) error {\n    if strings.HasPrefix(s, \"[\") {\n        if !strings.HasSuffix(s, \"]\") { return errors.New(\"missing closing ]\") }\n        for _, v := range strings.Split(strings.Trim(s, \"[]\"), \",\") {\n            if !semver.IsValid(strings.TrimSpace(v)) { return fmt.Errorf(\"bad bound %q\", v) }\n        }\n        return nil\n    }\n    if !semver.IsValid(s) { return fmt.Errorf(\"invalid version %q\", s) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the bracketed `[vLow,vHigh]` form for intervals.","Ensure both bounds carry the `v` prefix and are valid semver.","Validate with `semver.IsValid` in scripts that emit `go mod edit` commands."],"tags":["go-toolchain","go-mod","version","mod-edit"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}