NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #2818 by repository stars
Last release 1 months ago
18 Aug 2026
Ships unpredictably
gaps range from 1 weeks to 1.2 years
Some releases are documented
notes for 10 of 18 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
39 releases · first in 2019
ValidatorString.EqualFold and ValidatorStringP.EqualFold for case-insensitive string validation.
ValidatorString.EqualFold and ValidatorStringP.EqualFold for case-insensitive string validation.is.StringEqualFold and is.StringPEqualFold for the equivalent stateless predicates.EqualFold uses Go's strings.EqualFold Unicode simple case folding. It does not normalize text or apply full case folding. Pointer comparisons return false for nil values.
The following constructors are now deprecated compatibility aliases:
Valgo v0.9.0 modernizes the numeric constructor API around Go generics and introduces reusable stateless validation predicates.
The primary numeric constructors now accept every type in their respective families:
Int() and IntP() support all signed integer widths.Uint() and UintP() support all unsigned integer widths.Float() and FloatP() support float32 and float64.type Attempts int8
attempts := Attempts(3)
limit := uint32(100)
ratio := float32(0.75)
v.Int(attempts).Between(0, 5)
v.Uint(limit).GreaterThan(0)
v.Float(ratio).Between(0, 1)The specialized constructors originated before Go supported generics. With Valgo now targeting modern Go versions, separate constructors for every numeric width no longer provide additional behavior or type safety.
The following constructors are now deprecated compatibility aliases:
Int8, Int16, Int32, Int64, and their pointer variantsUint8, Uint16, Uint32, Uint64, and their pointer variantsFloat32, Float64, and their pointer variantsExisting code continues to work. New code should use Int, Uint, Float, and their pointer forms.
Rune/RuneP and Byte/ByteP remain supported because they communicate semantic meaning rather than only storage width.
The new github.com/cohesivestack/valgo/is package exposes Valgo’s built-in validation rules as type-safe boolean functions:
import "github.com/cohesivestack/valgo/is"
valid := !is.StringBlank(name) &&
is.StringLengthBetween(name, 2, 80) &&
is.IntGreaterOrEqualTo(stock, int16(0))These predicates can be used in ordinary Go control flow, application-specific validation helpers, and third-party validators that want to share Valgo’s rule semantics while providing their own contexts, errors, chaining, or localization.
Valgo’s built-in validators now use the same predicates internally, keeping their behavior aligned.
Migration only requires changing constructor names:
v.Int16(value) // Deprecated
v.Int(value) // Preferred
v.Float64P(&rate) // Deprecated
v.FloatP(&rate) // PreferredThe inferred value type and available validation rules remain unchanged.
One column per quarter.
Nothing published for this version
No breaking changes are intended in this release. Existing v0.8.0 code should continue to compile.
Valgo v0.8.1 is a backward-compatible release with shorter string length
validator names, clearer deprecation guidance, and refreshed docs.
String and StringP:ByteLength, ByteLengthBetween, Length, and LengthBetween.val := v.Is(
v.String("Bob", "full_name").Not().Blank().LengthBetween(4, 20),
)The older Of* string length methods remain available as deprecated aliases in
v0.8.1 and are planned for removal in v1.0:
OfByteLength -> ByteLengthOfByteLengthBetween -> ByteLengthBetweenOfLength -> LengthOfLengthBetween -> LengthBetweenDeprecation notes were also clarified for Validation.Error,
Validation.IsValid, and Validation.MergeErrorInRow. Prefer ToError,
PathValid, and MergeErrorInIndex.
No breaking changes are intended in this release. Existing v0.8.0 code should
continue to compile.
Nothing published for this version
IsValid() remains available but is deprecated in favor of PathValid() .
Valgo v0.8.0 introduces OrElse() short-circuiting, improved localized error messages for OR groups, validation-aware conditional flows, locale fallbacks for custom validators, and a new documentation website.
Or() continues to combine adjacent rules as alternatives within the same validator chain:
val := v.Is(
v.Int(status, "status").
EqualTo(1).
Or().EqualTo(2).
Or().EqualTo(3),
)When every alternative fails, Valgo now returns one localized message containing all failures:
Status must be equal to "1"; Status must be equal to "2"; or Status must be equal to "3"
OR grouping and precedence remain consistent with v0.7:
A.Or().B.C == (A OR B) AND C
A.B.Or().C == A AND (B OR C)
Localized OR formatting is available in English, Spanish, German, and Hungarian.
OrElse() operatorOrElse() introduces an OR boundary with short-circuiting. If the rule or OR group on its left succeeds, the remainder of the validator chain is skipped.
This is useful for accepting an optional value immediately and applying additional rules only when it is present:
val := v.Is(
v.String(value, "value").
Empty().
OrElse().
MinLength(5).
EqualTo("test"),
)This behaves as:
Empty() OR (MinLength(5) AND EqualTo("test"))
If Empty() succeeds, MinLength() and EqualTo() are not evaluated. Otherwise, validation continues through the rules on the right.
Like Or(), OrElse() takes no arguments and uses localized, joined error messages when all alternatives fail.
New methods make it easier to inspect results recorded in a validation session:
PathValid(path) checks a field or namespace.AllValid(paths...) returns whether every supplied path is valid.AnyValid(paths...) returns whether at least one supplied path is valid.IsValid() remains available but is deprecated in favor of PathValid().
New fluent methods can merge validations or execute callbacks based on the current validation results:
IfValid()IfPathValid()IfAllValid()IfAnyValid()WhenValid()WhenPathValid()WhenAllValid()WhenAnyValid()These methods help express dependent validation steps directly within a validation chain.
Custom validators can now provide default messages for their own error keys:
context.WithLocaleFallback(locale)Fallback entries are used only when the active locale does not already define the key. Built-in messages and consumer overrides continue to take precedence.
This release introduces comprehensive documentation powered by Astro and Starlight, including:
Explore the documentation at [valgo.build](https://valgo.build).
The generated Go API reference remains available at [pkg.go.dev/github.com/cohesivestack/valgo](https://pkg.go.dev/github.com/cohesivestack/valgo).
The repository now includes a Valgo Agent Skill for supported AI coding assistants:
npx skills add cohesivestack/valgo --skill valgoValgo v0.8 is tested with Go 1.23 and later. Using one of these versions is recommended.
go get github.com/cohesivestack/valgo@v0.8.0Full changelog: v0.7.1...v0.8.0
Nothing published for this version
Bump actions/checkout from 5 to 6 by @dependabot [bot] in #54 Full Changelog : v0.7.0...v0.7.1
IsValid()IsValid() now supports parent namespaces in nested validation structures. When a nested field is invalid, all parent namespaces are automatically marked as invalid, enabling conditional checks at any level of the object graph.
"person.addresses[0].line1" is invalid, parent namespaces ("person", "person.addresses", "person.addresses[0]") are also marked as invalidIsValid() behavior: IsValid() is now parent-namespace awarenessIn()) and indexed namespaces (InRow(), InCell())val := v.In("person",
v.InRow("addresses", 0,
v.Is(v.String("", "line1").Not().Blank()),
),
)
// Check validity at any namespace level
if !val.IsValid("person.addresses") {
// Handle address validation errors
}You keep your call sites; declared types may need a tweak (see “Breaking changes”).
This release focuses on two things: (1) fluent control over validation flow and (2) type-safe validators that remove codegen and width-specific types. PR: #50
InCell, If, When, DoInCell(name, index, v) — Run validators in an indexed namespace (great for slices of primitives or flat tables). Errors are grouped like phones[2].number, keeping messages precise without manual prefixing.If(condition, validation) — Conditionally merge another validation session. Perfect for optional blocks.When(condition, func(val *Validation)) — Like If, but runs a function to build rules. Keeps linear, readable control-flow.Do(func(val *Validation)) — Execute custom logic with access to the session (e.g., compute, branch, or attach custom errors).Why this matters: these helpers eliminate boilerplate if trees around validation, preserve explicit intent, and keep error paths tied to the exact field/cell that failed.
We replaced generated, width-specific validators with single generic types per family:
ValidatorInt[T ~int|~int8|~int16|~int32|~int64]ValidatorUint[T ~uint|~uint8|~uint16|~uint32|~uint64]ValidatorFloat[T ~float32|~float64]New rules include Positive()/Negative() for integers and NaN(), Infinite(), Finite() for floats. Constructors like v.Int16(...), v.Uint64(...), v.Float32(...) still work and now return the generic types. You keep your call sites; declared types may need a tweak (see “Breaking changes”).
Why this matters: less API surface, clearer autocompletion, fewer mistakes during refactors, and no codegen to maintain.
ValidatorComparable[T comparable] — Type-safe equality and membership: EqualTo, InSlice, plus Passing.ValidatorTyped[T] — A type-safe alternative to Any when you want custom rules on your own domain types without losing compile-time checks; includes Passing(func(T) bool) and Nil() for pointer forms.Why this matters: you keep Go’s type guarantees (no accidental cross-type comparisons) and still write concise, expressive rules.
Numeric validators: width-specific types (e.g., ValidatorInt16) are replaced by generics.
var a ValidatorInt16var a *ValidatorInt[int16]v.Int16(...), etc.) are unchanged.Any.EqualTo() is deprecated; use Comparable.EqualTo() to keep type-safety.
Validate items in a slice with stable error paths:
for i, phone := range phones {
val = val.InCell("phones", i, v.Is(
v.String(phone, "number").Not().Blank().OfLengthBetween(7, 15),
))
}Conditionally attach rules with If / When:
val.
If(hasMiddle, v.Is(v.String(m, "middle").OfLengthBetween(2, 50))).
When(isTrial, func(vv *v.Validation) {
vv.Is(v.Int(daysLeft, "days_left").GreaterThan(0))
})Comparable & Typed:
// Comparable
v.Is(v.Comparable(status, "status").InSlice([]Status{"active","paused"}))
// Typed custom rule
type Plan string
v.Is(v.Typed(plan, "plan").Passing(func(p Plan) bool { return p == "pro" || p == "team" }))Bottom line: v0.7.0 gives you cleaner control-flow (InCell/If/When/Do), safer equality and domain rules (Comparable, Typed), and a smaller, more coherent numeric API with new positivity/NaN/∞ checks—without disrupting most call sites.
Add rune length validators to support non-Latin alphabet languages by @mintc2 in #46
Full Changelog: v0.5.0...v0.6.0
The existing Error() function is now deprecated and will be removed in v1.0
This release introduces two new error handling functions for better Go integration:
ToError() Functionerror interfaceToValgoError() Function*valgo.Error typeError() FunctionError() function is now deprecated and will be removed in v1.0Before (deprecated):
val.Error() // Will be removed in v1.0After:
val.ToError() // For standard error handling
val.ToValgoError() // For detailed error informationFull Changelog: v0.4.2...v0.5.0
Nothing published for this version
Add support for Hungarian by @voroskoi in #31
Full Changelog: v0.4.1...v0.4.2
Add CI Workflow using GitHub Actions by @gaby in #20
Full Changelog: v0.4.0...v0.4.1
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →