golang/go · error

%s is not a directory

Error message

%s is not a directory

What it means

Thrown by `go work use` when fsys.Stat succeeds but info.IsDir() is false. The argument resolves to a regular file (or other non-directory entry), so it cannot be added as a workspace module directory. Reported via sw.Error and the loop continues to the next argument.

Source

Thrown at src/cmd/go/internal/workcmd/use.go:143

		if dup := keepDirs[absDir]; dup != "" && dup != dir {
			base.Errorf(`go: already added "%s" as "%s"`, dir, dup)
		}
		keepDirs[absDir] = dir
	}

	for _, useDir := range args {
		absArg, _ := pathRel(workDir, useDir)

		info, err := fsys.Stat(absArg)
		if err != nil {
			// Errors raised from os.Stat are formatted to be more user-friendly.
			if os.IsNotExist(err) {
				err = fmt.Errorf("directory %v does not exist", base.ShortPath(absArg))
			}
			sw.Error(err)
			continue
		} else if !info.IsDir() {
			sw.Error(fmt.Errorf("%s is not a directory", base.ShortPath(absArg)))
			continue
		}

		if !*useR {
			lookDir(useDir)
			continue
		}

		// Add or remove entries for any subdirectories that still exist.
		// If the root itself is a symlink to a directory,
		// we want to follow it (see https://go.dev/issue/50807).
		// Add a trailing separator to force that to happen.
		fsys.WalkDir(str.WithFilePathSeparator(useDir), func(path string, d fs.DirEntry, err error) error {
			if err != nil {
				return err
			}

			if !d.IsDir() {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Pass the directory containing the module, not the go.mod file: `go work use ./mymod` instead of `go work use ./mymod/go.mod`.
  2. Confirm with `test -d <path>` that the argument is a directory.
  3. If using a symlink, ensure it points at a directory, not a file.

Example fix

// before
go work use ./mymod/go.mod

// after
go work use ./mymod
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(p)
if err != nil {
    return fmt.Errorf("%s: %w", p, err)
}
if !info.IsDir() {
    return fmt.Errorf("%s is a file, pass the containing directory", p)
}

Prevention

When it happens

Trigger: Calling `go work use <file>` where <file> is a regular file (e.g. a .go source file, a go.mod file, a symlink to a file). The check at use.go:142 (`else if !info.IsDir()`) fires after a successful Stat.

Common situations: Pointing `go work use` at a go.mod file instead of its containing directory, dragging a file path from an editor, shell glob expanding to files, or following a tutorial that used the module file path rather than the directory.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/f7cdc3bbd3b00f77. Report an issue: GitHub.