jackwener/OpenCLI · error · EmptyResultError
goproxy module
goproxy module
Error message
proxy.golang.org returned no @latest entry for "${modulePath}". What it means
The goproxy module command queries proxy.golang.org's @latest endpoint for a Go module and throws this EmptyResultError when the response JSON is absent or has no Version field. It means the module proxy has no latest-version record for the module path — usually because the module doesn't exist there or was never resolved.
Source
Thrown at clis/goproxy/module.js:32
domain: 'proxy.golang.org',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'module', positional: true, type: 'string', required: true, help: 'Go module path (e.g. "github.com/gin-gonic/gin", "golang.org/x/net")' },
],
columns: [
'module', 'version', 'publishedAt', 'vcs', 'repository',
'commit', 'ref', 'pkgGoDevUrl', 'url',
],
func: async (args) => {
const modulePath = requireModulePath(args.module);
// GOPROXY spec requires lowercase percent-encoding for capital letters in the
// module path (e.g. github.com/Foo/Bar -> github.com/!foo/!bar). Module paths
// we accept here are lowercase-only by convention; we still encode each segment.
const encoded = modulePath.split('/').map(encodeURIComponent).join('/');
const detail = await goproxyJson(`${GOPROXY_BASE}/${encoded}/@latest`, `goproxy module ${modulePath}`);
if (!detail || !detail.Version) {
throw new EmptyResultError('goproxy module', `proxy.golang.org returned no @latest entry for "${modulePath}".`);
}
const origin = detail.Origin && typeof detail.Origin === 'object' ? detail.Origin : {};
return [{
module: modulePath,
version: String(detail.Version),
publishedAt: trimDate(detail.Time),
vcs: String(origin.VCS ?? '').trim(),
repository: String(origin.URL ?? '').trim(),
commit: String(origin.Hash ?? '').trim(),
ref: String(origin.Ref ?? '').trim(),
pkgGoDevUrl: `https://pkg.go.dev/${modulePath}`,
url: `${GOPROXY_BASE}/${encoded}/@latest`,
}];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the module path is correct and matches its go.mod declaration exactly (all lowercase)
- Ensure the module is public / has been fetched via the public proxy at least once (private modules need GOPRIVATE/GONOSUMDB and a different proxy)
- Query the proxy manually (curl https://proxy.golang.org/<module>/@latest) to confirm the 404
- If the module was renamed, use the new path; if deleted, pin an old version from a cache or fork
- Retry on transient proxy errors if the service is temporarily failing
Example fix
// before
const detail = await goproxyJson(`${GOPROXY_BASE}/${encoded}/@latest`, `goproxy module ${modulePath}`);
if (!detail || !detail.Version) throw new EmptyResultError('goproxy module', `...`);
// after
const path = modulePath.trim().toLowerCase();
const detail = await goproxyJson(`${GOPROXY_BASE}/${encodePath(path)}/@latest`, `goproxy module ${path}`);
if (!detail || !detail.Version) throw new EmptyResultError('goproxy module', `No @latest for "${path}" — check the module path is public and correct.`); Defensive patterns
Strategy: validation
Validate before calling
// validate module path before invoking
const mod = 'github.com/some/module';
if (!/^[a-z0-9][a-z0-9-.]*(:\/[a-z0-9-.]+)*$/.test(mod)) throw new Error('invalid module path: ' + mod);
// or verify it resolves first:
const res = await fetch(`https://proxy.golang.org/${mod}/@v/list`);
if (!res.ok) throw new Error('module not on proxy: ' + mod); Type guard
function hasLatestEntry(detail) {
return detail != null && typeof detail === 'object' && typeof detail.Version === 'string' && detail.Version.length > 0;
} Try / catch
try {
return await goproxyModuleCommand.func({module: mod});
} catch (e) {
if (String(e.message).includes('no @latest entry')) {
throw new Error(`Module "${mod}" not found on proxy.golang.org — check spelling and that it is public`);
}
throw e;
} Prevention
- Double-check module paths for typos before querying
- Remember module paths are lowercase; encode segments per GOPROXY spec
- Private modules need GOPRIVATE/GOPROXY config — the public proxy will 404 them
- Deleted/renamed modules return no @latest; verify the repo still exists
When it happens
Trigger: goproxyJson(GOPROXY_BASE/<encoded>/@latest, ...) returns null/undefined (e.g. HTTP 404/410 from the proxy) or an object without a truthy Version property — for misspelled module paths, private modules not published to the public proxy, or deleted/retracted modules.
Common situations: Typo in the module path (e.g. wrong repo name); module exists only in a private repo/VCS and was never fetched by proxy.golang.org; module author removed the repo; capital letters not expected (the code assumes lowercase module paths per GOPROXY encoding); proxy service outage returning empty bodies.
Related errors
- bilibili creator-stats ${bvid}
- Chess.com returned 404 for ${url}
- crates crate
- crates.io returned 404 for ${url}.
- Photo ID ${requestedPhotoId} was not found under subject ${s
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/912bcedb6fbbf822.
Report an issue: GitHub.