{"record":{"id":"e831da6d05979183","repo":"alibaba/open-code-review","slug":"walk-s-w","errorCode":null,"errorMessage":"walk %s: %w","messagePattern":"walk (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/scan/provider.go","lineNumber":240,"sourceCode":"\t\tif d.IsDir() {\n\t\t\t// Skip the whole subtree if the dir itself is excluded.\n\t\t\tif diff.IsPathExcluded(p.repoDir, rel, gitignorePatterns) {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\t// Regular files only; skip symlinks / sockets / etc.\n\t\tif !d.Type().IsRegular() {\n\t\t\treturn nil\n\t\t}\n\t\tif diff.IsPathExcluded(p.repoDir, rel, gitignorePatterns) {\n\t\t\treturn nil\n\t\t}\n\t\tfiles = append(files, rel)\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"walk %s: %w\", p.repoDir, err)\n\t}\n\treturn files, nil\n}\n\nfunc (p *Provider) gitLs(ctx context.Context, args ...string) ([]string, error) {\n\tcmdArgs := append([]string{\"-c\", \"core.quotepath=false\", \"ls-files\"}, args...)\n\tvar out string\n\tvar err error\n\tif p.runner != nil {\n\t\tout, err = p.runner.Run(ctx, p.repoDir, cmdArgs...)\n\t} else {\n\t\tcmd := exec.CommandContext(ctx, \"git\", cmdArgs...)\n\t\tcmd.Dir = p.repoDir\n\t\t// Use Output (stdout only), not CombinedOutput: with -z, git emits\n\t\t// NUL-delimited paths on stdout, and merging stderr in would corrupt\n\t\t// the filename parsing below.\n\t\traw, runErr := cmd.Output()\n\t\tout, err = string(raw), runErr","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/scan/provider.go#L222-L258","documentation":"In non-git directories, listFiles falls back to filepath.WalkDir (listFilesViaWalk). Any error returned by the walk (other than skipped entries) is wrapped as 'walk <repoDir>: ...'. Note per-entry errors are logged and skipped, so this surfaces only for fatal errors like context cancellation or the root being unreadable.","triggerScenarios":"Provider.listFiles → listFilesViaWalk when the directory is not a git repo, and filepath.WalkDir returns a non-nil error — almost always ctx.Err() (cancellation/deadline) propagated by the callback, or the root directory itself being inaccessible.","commonSituations":"Scanning a plain (non-git) folder whose root lacks read permission; scan timeout/cancel mid-walk; repoDir pointing at a nonexistent path.","solutions":["Check the wrapped cause: if it is 'context deadline exceeded', raise the timeout or re-run.","Ensure the scanned directory exists and is readable (ls the directory as the running user).","Run `git init` if the directory should be a git repo, to use the more robust git path.","Re-run pointing at the correct directory path."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"info, err := os.Stat(repoDir)\nif err != nil || !info.IsDir() {\n    return fmt.Errorf(\"cannot walk %s: not a readable directory\", repoDir)\n}\nif _, err := os.ReadDir(repoDir); err != nil {\n    return fmt.Errorf(\"directory not readable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"files, err := provider.Enumerate(ctx)\nif err != nil {\n    if errors.Is(err, context.DeadlineExceeded) {\n        return fmt.Errorf(\"walk exceeded timeout: %w\", err) // retry with bigger timeout\n    }\n    return err\n}","preventionTips":["Verify the target directory exists and is readable before scanning.","Initialize a git repo to use the more robust git-based enumeration.","Provide sufficient timeout for large directory trees.","Point the scan at the correct path; walk errors surface only for fatal issues."],"tags":["filesystem","walk","file-enumeration"],"backgroundTag":"directory-not-readable","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}