Skip to content

[BUG] .rooignore rules not enforced for codebase indexing, file reads, or environment file listingΒ #11797

@frbrdan-code

Description

@frbrdan-code

Problem (one or two sentences)

.rooignore entries are completely ignored β€” directories listed in .rooignore are still indexed by codebase search, readable via read_file, and shown without πŸ”’ icons in the auto-generated environment file listing.

Context (who is affected and when)

Affects any user with a .rooignore file in a workspace that contains git submodules or deeply nested third-party directories. The issue is visible immediately when the AI assistant accesses files that should be blocked. Particularly problematic for workspaces with large vendored/third-party code that users explicitly want to exclude.

Reproduction steps

  1. Environment: Roo Code v3.50.4, Linux, any API provider (tested with Anthropic Claude Opus).

  2. Setup: Create a workspace that contains a git submodule (a separate git repository nested inside the main repo):

    mkdir my-project && cd my-project && git init
    mkdir src && echo "int main() {}" > src/main.c
    # Add a git submodule β€” this creates vendor/some-lib/ with its own .git
    git submodule add https://github.com/some-org/some-lib.git vendor/some-lib

    Resulting structure:

    my-project/
    β”œβ”€β”€ .git/
    β”œβ”€β”€ .gitmodules            ← records the submodule
    β”œβ”€β”€ .rooignore
    β”œβ”€β”€ src/
    β”‚   └── main.c
    └── vendor/
        └── some-lib/          ← git submodule (has its own .git inside)
            β”œβ”€β”€ .git           ← this makes it a separate git repo
            β”œβ”€β”€ Makefile
            β”œβ”€β”€ drivers/
            β”‚   └── crypto.c
            β”œβ”€β”€ include/
            β”‚   └── crypto-engine.h
            └── tests/
                └── test-basic.c
    

    The key detail is that vendor/some-lib/ is a git submodule β€” it has its own .git directory, making it a repo-inside-a-repo.

  3. Create .rooignore at the workspace root with:

    vendor/some-lib/
    
  4. Start a new Roo Code task.

  5. Use codebase_search scoped to vendor/some-lib with any query (e.g., "crypto"). Observe: 50+ indexed results are returned from inside the ignored directory.

  6. Use read_file on vendor/some-lib/Makefile. Observe: file content is returned successfully with no access-denied error.

  7. Check environment_details auto-generated file listing. Observe: vendor/some-lib/ files appear without the πŸ”’ lock icon.

Expected result

.rooignore should block codebase indexing, file reads, and show πŸ”’ icons for all files matching the ignore patterns.

Actual result

All three enforcement mechanisms fail β€” files inside .rooignore-listed directories are indexed, readable, and displayed without lock icons, as if .rooignore does not exist.

Variations tried (optional)

  • Tested with multiple .rooignore entries (several different vendor/ subdirectories) β€” none are enforced
  • The directories in question are git submodules (have their own .git directory inside), but the issue may not be submodule-specific
  • The .rooignore file is confirmed to exist at the workspace root with valid .gitignore-syntax patterns
  • Testing with a non-submodule directory would help isolate whether git submodules specifically cause the issue vs. a general .rooignore enforcement failure

App Version

v3.50.4

API Provider (optional)

Anthropic

Model Used (optional)

Claude Opus 4.6

Roo Code Task Links (optional)

No response

Relevant logs or errors (optional)

No errors in the Output panel β€” the failure is silent. `.rooignore` patterns are simply not applied.

**Likely root causes from source analysis:**

1. `RooIgnoreController.validateAccess()` (`src/core/ignore/RooIgnoreController.ts:89`) returns `true` (allow access) if `rooIgnoreContent` is undefined β€” which happens when the `.rooignore` file fails to load or the controller is initialized with the wrong `cwd`.

2. The scanner (`src/services/code-index/processors/scanner.ts:87`) creates a **new** `RooIgnoreController(directoryPath)` β€” if `directoryPath` differs from the workspace root where `.rooignore` lives, the controller won't find the file and silently allows everything.

3. `validateAccess()` calls `realpathSync()` on line 100 which follows symlinks. For git submodules, this may resolve to a path outside `cwd`, causing `path.relative()` to produce an unexpected result, and the catch block on line 113 defaults to **allowing access**.

4. The search service (`src/services/code-index/search-service.ts`) queries Qdrant directly with no post-query `.rooignore` filtering β€” once files are indexed, they appear in search results permanently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions