Skip to content

fix(tools): guard concurrent gitignore and screenshot caches#713

Merged
edenreich merged 1 commit into
inference-gateway:mainfrom
somaz94:fix/tools-concurrent-cache-race
Jul 2, 2026
Merged

fix(tools): guard concurrent gitignore and screenshot caches#713
edenreich merged 1 commit into
inference-gateway:mainfrom
somaz94:fix/tools-concurrent-cache-race

Conversation

@somaz94

@somaz94 somaz94 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

The Tree tool's gitignoreCache map was read and written without synchronization in getOrLoadDirGitignore. Tools run concurrently within a turn (up to MaxConcurrentTools), so two Tree executions could touch the map at once and trigger a fatal "concurrent map read and map write", killing the infer process. This mirrors the RWMutex + double-checked lock the Grep tool already uses.

Also guards GetLatestScreenshotTool.lastCallTime (read/write in Execute) with a sync.Mutex, as the issue requested, since it is the same singleton plus concurrent-goroutine class.

Validation:

  • go test -race ./internal/agent/tools/ passes; the new TestTreeTool_ConcurrentGitignoreCache fatals with "concurrent map writes" without the fix and passes with it
  • golangci-lint run: 0 issues; go vet clean; go fmt and go mod tidy leave the tree clean

Fixes #712

somaz94 added a commit to somaz94/somaz94 that referenced this pull request Jul 2, 2026
@somaz94 somaz94 marked this pull request as ready for review July 2, 2026 09:23
@somaz94 somaz94 requested a review from a team as a code owner July 2, 2026 09:23
@edenreich

Copy link
Copy Markdown
Contributor

@infer Can you review this?

@inference-gateway-maintainer

inference-gateway-maintainer Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

View Job

Todos

  • Understand the current state of the branch and what changes are needed
  • Guard gitignoreCache in Tree tool with RWMutex + double-checked lock
  • Guard GetLatestScreenshotTool.lastCallTime with sync.Mutex
  • Add/update tests for concurrent access
  • Run go vet, go fmt, go mod tidy, and golangci-lint

✅ Infer Result: Success

Summary

The PR #713 changes are already fully implemented in commit 770855a on this branch. Here's the current state:

Changes Implemented (3 files, +67/-1)

1. internal/agent/tools/tree.go — Guard gitignoreCache with sync.RWMutex

  • Added cacheMutex sync.RWMutex field to TreeTool struct
  • Added "sync" import
  • getOrLoadDirGitignore now uses a double-checked locking pattern:
    1. Fast path: RLock → check cache → RUnlock (return cached if hit)
    2. Slow path: Lock → double-check → load/insert → defer Unlock

This mirrors the same pattern the Grep tool already uses for its own cache.

2. internal/agent/tools/get_latest_screenshot.go — Guard lastCallTime with sync.Mutex

  • Added lastCallMu sync.Mutex field to GetLatestScreenshotTool struct
  • Added "sync" import
  • Execute now locks the mutex around the lastCallTime read/write critical section, unlocking before early returns and after the write

3. internal/agent/tools/tree_test.go — New concurrent test

  • Added TestTreeTool_ConcurrentGitignoreCache: spawns 8 goroutines each doing 100 iterations over 16 directories (half with .gitignore files), calling getOrLoadDirGitignore concurrently. Without the mutex this triggers a fatal "concurrent map writes" under -race.

Validation Results

Check Result
go test -race ./internal/agent/tools/ PASS (8.94s, all tests including the new concurrent one)
go vet ./internal/agent/tools/ CLEAN (no output)
go fmt ./internal/agent/tools/ CLEAN (no changes)
go mod tidy CLEAN (no changes)
CI (prepare, lint, vet, build, test) All SUCCESS

PR Status

  • State: OPEN
  • Mergeable: MERGEABLE
  • Merge state: BLOCKED (likely needs a review — 0 reviews so far)
  • CI: All 5 checks passing
  • Head branch: somaz94/cli:fix/tools-concurrent-cache-race (fork — we cannot push to it from this runner)

The PR is complete and ready for review. The only remaining action is for a maintainer to approve and merge it.

Model: ollama_cloud/deepseek-v4-flash · Exit Code: 0 · Duration: 4m 5s

Tokens: 954,610 in · 3,915 out · 958,525 total (20 requests)

Tool calls: 26 total · 85% success rate

⚠️ 4 failed tool call(s)
  • Bash: exit status 128: fatal: origin/main...HEAD: no merge base
  • Bash: exit status 2: make: *** No rule to make target 'lint'. Stop.
  • Bash: exit status 2: Taskfile.yml
  • Bash: exit status 201: �[32mtask: [lint] golangci-lint run
    �[0m"golangci-lint": executable file not found in $PATH
    ::error title=Task 'lint' failed::exit status 127
    �[31mtask: Failed to run task "lint": exit status 127
    �[0m

Triggered by edenreich · Infer Action

@edenreich edenreich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. thanks!

@edenreich edenreich merged commit 0ff4276 into inference-gateway:main Jul 2, 2026
inference-gateway-releaser Bot added a commit that referenced this pull request Jul 2, 2026
## [0.127.0](v0.126.0...v0.127.0) (2026-07-02)

### 🚀 Features

* **plan:** compact context and start a fresh session when a plan is approved ([#705](#705)) ([28ddba7](28ddba7))
* **memory:** configurable git sync backend ([#707](#707)) ([6a68c3d](6a68c3d)), closes [#670](#670) [#670](#670)
* **history:** each subagent gets its own history file ([#711](#711)) ([16c8fa1](16c8fa1)), closes [#699](#699)

### 🐛 Bug Fixes

* **plan:** accepting a plan switches to auto-accept mode by default ([#714](#714)) ([7b0befc](7b0befc)), closes [#710](#710)
* **tools:** guard concurrent gitignore and screenshot caches ([#713](#713)) ([0ff4276](0ff4276)), closes [#712](#712)
* **tools:** guard Registry.tools with RWMutex against concurrent MCP registration ([#709](#709)) ([8a70871](8a70871)), closes [#708](#708)
* **ui:** update dim color from [#565f89](https://github.com/inference-gateway/cli/issues/565f89) to [#7a7f9a](https://github.com/inference-gateway/cli/issues/7a7f9a) for improved contrast ([#706](#706)) ([b2ee67e](b2ee67e))

### 🔧 Build System

* **deps:** bump github.com/go-telegram/bot from 1.21.0 to 1.22.0 in the gomod group ([#703](#703)) ([3de5136](3de5136))
* **deps:** bump the github-actions group with 5 updates ([#704](#704)) ([80221f7](80221f7))
@inference-gateway-releaser

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 0.127.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Tree tool crashes the process with "concurrent map read and map write" (unsynchronized gitignoreCache)

2 participants