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

  1. Verify the module path is correct and matches its go.mod declaration exactly (all lowercase)
  2. Ensure the module is public / has been fetched via the public proxy at least once (private modules need GOPRIVATE/GONOSUMDB and a different proxy)
  3. Query the proxy manually (curl https://proxy.golang.org/<module>/@latest) to confirm the 404
  4. If the module was renamed, use the new path; if deleted, pin an old version from a cache or fork
  5. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/912bcedb6fbbf822. Report an issue: GitHub.