golangci/golangci-lint · critical

Can't get working dir: %s

Error message

Can't get working dir: %s

What it means

NewPathShortener panics immediately if it cannot determine the current working directory via fsutils.Getwd, since path shortening is meaningless without it. Unlike errors 264, this constructor fails hard via panic rather than returning an error.

Source

Thrown at pkg/result/processors/path_shortener.go:22

	"fmt"
	"strings"

	"github.com/golangci/golangci-lint/v2/pkg/fsutils"
	"github.com/golangci/golangci-lint/v2/pkg/result"
)

var _ Processor = (*PathShortener)(nil)

// PathShortener modifies text of the reports to reduce file path inside the text.
// It uses the rooted path name corresponding to the current directory (`wd`).
type PathShortener struct {
	wd string
}

func NewPathShortener() *PathShortener {
	wd, err := fsutils.Getwd()
	if err != nil {
		panic(fmt.Sprintf("Can't get working dir: %s", err))
	}

	return &PathShortener{wd: wd}
}

func (PathShortener) Name() string {
	return "path_shortener"
}

func (p PathShortener) Process(issues []*result.Issue) ([]*result.Issue, error) {
	return transformIssues(issues, func(issue *result.Issue) *result.Issue {
		newIssue := issue
		newIssue.Text = strings.ReplaceAll(newIssue.Text, p.wd+"/", "")
		newIssue.Text = strings.ReplaceAll(newIssue.Text, p.wd, "")
		return newIssue
	}), nil
}

View on GitHub (pinned to ed7a235d2d)

Solutions

  1. Run golangci-lint from a valid, existing directory (cd into the project)
  2. Recreate the deleted working directory before running the linter
  3. Fix sandbox/permission settings so the process can access its current directory
  4. If embedding the library, ensure NewPathShortener is only called after confirming os.Getwd() works

Example fix

// before
os.RemoveAll(tmpDir) // still cwd
p := processors.NewPathShortener() // panics
// after
os.Chdir(projectDir)
os.RemoveAll(tmpDir)
p := processors.NewPathShortener()
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Getwd(); err != nil {
    // do not construct runners/shorteners from a dead cwd
    os.Chdir("/") // or the project dir
}

Try / catch

func safeRun() (err error) {
    defer func() {
        if r := recover(); r != nil {
            if s, ok := r.(string); ok && strings.HasPrefix(s, "Can't get working dir") {
                err = fmt.Errorf("cwd unavailable: %s", s)
            } else { panic(r) }
        }
    }()
    processors.NewPathShortener()
    return nil
}

Prevention

When it happens

Trigger: Constructing NewPathShortener (during NewRunner) while os.Getwd fails: the current directory was deleted, or the process lacks permission to stat its cwd.

Common situations: Executing golangci-lint from a removed temp/build directory; test harnesses deleting the cwd mid-run; restricted sandboxes/containers where cwd lookup fails.

Related errors


AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02). Data as JSON: /api/errors/83a6e62d03626a17. Report an issue: GitHub.