#22723: fix: guard against undefined path in buildInjectedWorkspaceFiles — prevents agent crash-loop (#22693)
agents
size: XS
Cluster:
Bootstrap and Plugin Fixes
## Summary
A hook-injected file with a missing `path` property (e.g. using `filePath` instead of `path`) crashes **every agent on every message** with:
```
TypeError: Cannot read properties of undefined (reading 'replace')
at buildInjectedWorkspaceFiles (reply-B4B0jUCM.js:26612:36)
at buildSystemPromptReport (reply-B4B0jUCM.js:26682:27)
at runEmbeddedAttempt (reply-B4B0jUCM.js:54231:30)
```
Fixes #22693
---
## Root Cause
`buildInjectedWorkspaceFiles()` iterates `params.injectedFiles` and calls `file.path.replace(...)` without checking that `file.path` is defined. `EmbeddedContextFile.path` is typed as `string`, but hook code bypasses TypeScript at runtime. One malformed file brings down all agents silently.
**Before (crashes on `undefined.replace`):**
```typescript
const injectedByPath = new Map(params.injectedFiles.map((f) => [f.path, f.content]));
for (const file of params.injectedFiles) {
const normalizedPath = file.path.replace(/\\/g, "/"); // 💥 if path is undefined
```
## Fix
Filter out files with undefined `path` before building lookup maps, and emit a `console.warn` so the bad hook is identifiable from logs:
```typescript
const validInjectedFiles = params.injectedFiles.filter((f) => {
if (!f.path) {
console.warn(
`[buildInjectedWorkspaceFiles] Skipping injected file "${f.name ?? "(unnamed)"}" — missing required \`path\` property`,
);
return false;
}
return true;
});
const injectedByPath = new Map(validInjectedFiles.map((f) => [f.path, f.content]));
for (const file of validInjectedFiles) {
const normalizedPath = file.path.replace(/\\/g, "/"); // ✅ safe
```
## Testing
- [x] TypeScript compiles cleanly (change is additive — filter + warn)
- [ ] Untested against a live hook reproducing the crash
AI-assisted: implemented with Claude (Prometheus/OpenClaw agent), reviewed by author.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds defensive guard to prevent agent crash-loop when hook-injected files have undefined `path` property. The fix filters out invalid files and logs a warning for debugging.
- Guards against `undefined.replace()` crash in `buildInjectedWorkspaceFiles()`
- Filters invalid files before creating lookup maps
- Adds warning log to help identify misconfigured hooks
- Warning message references non-existent `f.name` property (should use `f.path` or remove identifier)
<h3>Confidence Score: 4/5</h3>
- Safe to merge with one minor fix needed for warning message
- The defensive guard correctly prevents the crash described in #22693, and the filtering logic is sound. However, the warning message references `f.name` which doesn't exist on `EmbeddedContextFile`, reducing the usefulness of the debug output. This is a minor issue that doesn't affect the core fix.
- Fix the warning message in `src/agents/system-prompt-report.ts:48` to remove the undefined `f.name` reference
<sub>Last reviewed commit: a65a64a</sub>
<!-- greptile_other_comments_section -->
<sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#18647: fix(agents): guard against undefined paths in injectedFiles
by kleinpanic · 2026-02-16
86.5%
#21954: Prevent bootstrap hook truncation crash in prompt report
by graysurf · 2026-02-20
82.4%
#22786: fix: guard against undefined file.path in system-prompt-report
by miloudbelarebia · 2026-02-21
79.1%
#13415: fix(hooks): bridge agent_end events to internal/workspace hooks
by mcaxtr · 2026-02-10
75.2%
#19177: fix: use parseAgentSessionKey instead of fragile split pattern
by El-Patronum · 2026-02-17
74.6%
#7301: fix(hooks): use resolveAgentIdFromSessionKey instead of split(":")[0]
by tsukhani · 2026-02-02
74.6%
#23019: fix(hooks): use globalThis singleton for internal hooks handlers Map
by karmafeast · 2026-02-21
74.5%
#9947: fix: preserve agent-events as standalone entry point for hook consu...
by therealkaiharper-wq · 2026-02-05
74.4%
#16915: fix: await compaction hooks with timeout to prevent cross-session d...
by maximalmargin · 2026-02-15
74.0%
#19422: fix: pass session context to plugin tool hooks in toToolDefinitions
by namabile · 2026-02-17
73.9%