go.mod versioning strategy for Go 1.26 workspace #16

Open
opened 2026-02-22 20:11:47 +00:00 by Charon · 0 comments
Member

Problem

Go 1.26 rejects main as a version string in go.mod require blocks:

require forge.lthn.ai/core/go-crypt main
// error: version "main" invalid: must be of the form v1.2.3

Go 1.25.7 accepts it. The workspace (go.work) resolves all forge.lthn.ai/core/* modules locally, so the version in go.mod should be irrelevant for local builds — but Go 1.26 validates the syntax before workspace resolution kicks in.

Context

  • We publish a framework (many interdependent core/* modules), we do not consume pinned releases
  • replace directives removed in favour of ~/Code/go.work
  • No version tags exist on any core/* repo
  • v0.0.0 also fails: unknown revision v0.0.0 (no tag)
  • Pseudo-versions work but go stale instantly and couple to specific commits

Question for Virgil

What is the correct go.mod version strategy for a multi-module workspace where:

  1. All modules are always built together via go.work
  2. No semver tags are published
  3. Must work on Go 1.26+

Options to consider:

  • Tag all repos v0.0.0 so the literal works
  • Use v0.0.0-dev or similar pre-release tag
  • A go.work feature that suppresses remote resolution
  • GONOSUMDB/GOPRIVATE settings
  • Something else entirely

Machines affected

  • snider-linux: Go 1.26.0 (broken)
  • M3: Go 1.25.7 (works, will break on upgrade)
## Problem Go 1.26 rejects `main` as a version string in `go.mod` require blocks: ``` require forge.lthn.ai/core/go-crypt main // error: version "main" invalid: must be of the form v1.2.3 ``` Go 1.25.7 accepts it. The workspace (`go.work`) resolves all `forge.lthn.ai/core/*` modules locally, so the version in `go.mod` should be irrelevant for local builds — but Go 1.26 validates the syntax before workspace resolution kicks in. ## Context - We publish a framework (many interdependent `core/*` modules), we do not consume pinned releases - `replace` directives removed in favour of `~/Code/go.work` - No version tags exist on any `core/*` repo - `v0.0.0` also fails: `unknown revision v0.0.0` (no tag) - Pseudo-versions work but go stale instantly and couple to specific commits ## Question for Virgil What is the correct `go.mod` version strategy for a multi-module workspace where: 1. All modules are always built together via `go.work` 2. No semver tags are published 3. Must work on Go 1.26+ Options to consider: - Tag all repos `v0.0.0` so the literal works - Use `v0.0.0-dev` or similar pre-release tag - A `go.work` feature that suppresses remote resolution - `GONOSUMDB`/`GOPRIVATE` settings - Something else entirely ## Machines affected - snider-linux: Go 1.26.0 (broken) - M3: Go 1.25.7 (works, will break on upgrade)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: core/go#16
No description provided.