Skip to content

fix(smart_read): guard zod-v4 ZodError and require non-empty path#167

Open
nilhemdot wants to merge 1 commit into
ooples:masterfrom
nilhemdot:fix/smart-read-zod-v4-crash
Open

fix(smart_read): guard zod-v4 ZodError and require non-empty path#167
nilhemdot wants to merge 1 commit into
ooples:masterfrom
nilhemdot:fix/smart-read-zod-v4-crash

Conversation

@nilhemdot
Copy link
Copy Markdown

Problem

smart_read crashed with Cannot read properties of undefined (reading 'map') on any validation failure.

Root cause: validateToolArgs reads error.errors, which zod v4 removed in favor of error.issues. The published package bundles zod 4.x, so error.errors is undefinedundefined.map(...). Any bad argument (e.g. calling with the wrong key file_path instead of path) triggers it.

Changes

  • src/validation/validator.ts — read error.issues ?? error.errors ?? [], so error formatting works on both zod v3 and v4 and can never crash on a malformed ZodError.
  • src/tools/file-operations/smart-read.ts — guard a missing/blank path with a clear smart_read requires a non-empty "path" argument message instead of an opaque downstream error.
  • docs/TESTING_INSTRUCTIONS.md — rewritten for the WSL2/Linux native port: correct path argument, daemon/invoke-mcp.js invocation, WSL paths (dispatcher.log, ~/.token-optimizer-cache/cache.db), the dedup-based Read interception model, and a regression test for the .map crash.
  • Version bump → 5.0.2.

Verification

End-to-end through the daemon socket:

  • {file_path: ...} (bad arg) → Validation failed for tool "smart_read": - path: Invalid input: expected string, received undefinedno .map crash.
  • {path: ...} (correct) → works, fromCache: true.

🤖 Generated with Claude Code

validateToolArgs read `error.errors`, which zod v4 removed in favor of
`error.issues`, so any failed validation crashed with
"Cannot read properties of undefined (reading 'map')". Read
`error.issues ?? error.errors ?? []` so error formatting works on both
zod v3 and v4.

Also guard smart_read against a missing/blank `path` (e.g. the wrong key
`file_path`) with a clear message instead of an opaque downstream error.

Rewrite docs/TESTING_INSTRUCTIONS.md for the WSL2 native port: correct
`path` argument, daemon/invoke-mcp.js invocation, WSL paths, the
dedup-based Read interception model, and a regression test for the crash.

Bump version to 5.0.2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Review Change Stack

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Fixed validation error handling that previously caused crashes when processing malformed data
    • Added stricter path validation to fail fast on missing or invalid arguments
  • Build & Deployment

    • Dashboard static assets are now automatically included in production builds
  • Documentation

    • Updated testing instructions with comprehensive setup guidance and expanded platform support

Walkthrough

This PR delivers v5.0.2 with two bug fixes for argument validation and Zod error handling, updates npm build scripts to include dashboard asset copying, and extensively revises testing documentation to reflect the new WSL2/Linux daemon-based workflow with caching, diff, and truncation metadata.

Changes

v5.0.2 Release — Validation Fixes and Build Updates

Layer / File(s) Summary
Zod error handling and filePath validation
src/validation/validator.ts, src/tools/file-operations/smart-read.ts, CHANGELOG.md
Zod validation error handling now normalizes across v3/v4 by reading error.issues or error.errors with fallback; SmartReadTool.read adds early guard to validate filePath is a non-empty string; both fixes documented in changelog.
Build pipeline updates and version bump
package.json
Package version incremented to 5.0.2; new copy:assets npm script copies dashboard public files into dist; build, dashboard:dev, and dashboard:build scripts all integrate asset copying into their pipelines.

Testing Documentation — v5.0.1 WSL2/Linux Workflow

Layer / File(s) Summary
Prerequisites and daemon setup validation
docs/TESTING_INSTRUCTIONS.md (lines 1–26)
Prerequisites updated to require built/installed smart_read v5.0.1, daemon validation, Unix socket checks, and WSL-native hook installation; documents argument validation and fallback for missing/incorrect path.
Interception model and standalone invocation
docs/TESTING_INSTRUCTIONS.md (lines 37–61)
WSL-specific explanation: unchanged-file re-reads denied via context dedup; smart_read invoked explicitly or via daemon for caching/diff/truncation; adds standalone invocation using invoke-mcp.js and metadata field inspection.
Test scenarios with new metadata contracts
docs/TESTING_INSTRUCTIONS.md (lines 61–128)
Five test scenarios reworked to match daemon behavior: cache hits, cross-session SQLite persistence, diff-only results, 100KB truncation threshold, and validation failure for bad arguments; removes old orchestrator-tied patterns.
Troubleshooting, performance, and architecture
docs/TESTING_INSTRUCTIONS.md (lines 129–181)
Troubleshooting updated with .map crash root cause and path vs file_path guidance; performance expectations match new caching/diff/truncation semantics; notes emphasize WSL2/Linux daemon + shared TMPDIR.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A patch of fixes hops along,
Zod errors mended, strong and long!
Dashboard assets copied clean,
Docs refreshed with Linux's sheen—
v5.0.2 bounces home! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main changes: fixing a Zod v4 ZodError crash and requiring non-empty path validation in smart_read.
Description check ✅ Passed The PR description is comprehensive, covering the problem, root cause, specific code changes, documentation updates, version bump, and verification steps. It aligns well with the template's key sections.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Commit Message Format Issue

Your commit messages don't follow the Conventional Commits specification.

Required Format:

<type>(<optional scope>): <description>

[optional body]

[optional footer]

Valid Types:

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that don't affect code meaning (white-space, formatting)
  • refactor: Code change that neither fixes a bug nor adds a feature
  • perf: Code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • build: Changes that affect the build system or external dependencies
  • ci: Changes to CI configuration files and scripts
  • chore: Other changes that don't modify src or test files
  • revert: Reverts a previous commit

Examples:

feat(auth): add OAuth2 authentication
fix(api): resolve race condition in token refresh
docs(readme): update installation instructions
refactor(core): simplify token optimization logic

Breaking Changes:

Add BREAKING CHANGE: in the footer or append ! after the type:

feat!: remove deprecated API endpoints

Please amend your commit messages to follow this format.

Learn more: Conventional Commits

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/TESTING_INSTRUCTIONS.md`:
- Line 134: Update the two references of the package version string "v5.0.1" to
"v5.0.2" in the document (the occurrences noted in the diff), ensuring both
instances are changed (including the line containing "**Fix**: Fixed in v5.0.1
(`error.issues ?? error.errors ?? []`). Rebuild" and the second occurrence
around line 142) so the docs match the package version.
- Line 1: Update the document title "Testing Instructions for smart_read Caching
(v5.0.1)" and the other in-text occurrence of "v5.0.1" to "v5.0.2" so the file
matches the PR objective "Bumped package version to 5.0.2"; locate the exact
title string and any standalone "v5.0.1" tokens in the document and replace them
with "v5.0.2".

In `@src/tools/file-operations/smart-read.ts`:
- Around line 107-111: The validation in smart_read currently only rejects
non-strings and empty strings but allows whitespace-only paths; update the check
around the filePath variable in src/tools/file-operations/smart-read.ts so that
after confirming typeof filePath === 'string' you also treat strings with only
whitespace as invalid (e.g., use filePath.trim().length === 0 or a /^\s*$/ test)
and throw the same error; ensure you don't call trim() before the typeof check
so you avoid calling string methods on non-strings and keep the error message
thrown by the existing smart_read validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6aae9847-ce7b-4d61-bc66-5556550150f7

📥 Commits

Reviewing files that changed from the base of the PR and between 45a76c3 and 85d6f46.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/TESTING_INSTRUCTIONS.md
  • package.json
  • src/tools/file-operations/smart-read.ts
  • src/validation/validator.ts

@@ -1,161 +1,181 @@
# Testing Instructions for smart_read Caching (v2.4.0)
# Testing Instructions for smart_read Caching (v5.0.1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Version mismatch: document references v5.0.1 but package is v5.0.2.

The title and line 8 reference v5.0.1, but the PR objectives state "Bumped package version to 5.0.2." Update both instances to v5.0.2 for consistency.

📝 Proposed fix
-# Testing Instructions for smart_read Caching (v5.0.1)
+# Testing Instructions for smart_read Caching (v5.0.2)
-1. ✅ Package built/installed at v5.0.1 (`smart_read` tool present).
+1. ✅ Package built/installed at v5.0.2 (`smart_read` tool present).

Also applies to: 8-8

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/TESTING_INSTRUCTIONS.md` at line 1, Update the document title "Testing
Instructions for smart_read Caching (v5.0.1)" and the other in-text occurrence
of "v5.0.1" to "v5.0.2" so the file matches the PR objective "Bumped package
version to 5.0.2"; locate the exact title string and any standalone "v5.0.1"
tokens in the document and replace them with "v5.0.2".

### Issue: "Cannot read properties of undefined (reading 'map')"
**Cause**: Old build — `validator.ts` read `error.errors`, removed in zod v4
(the global package bundles zod 4.x), so it was `undefined.map`.
**Fix**: Fixed in v5.0.1 (`error.issues ?? error.errors ?? []`). Rebuild
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update version references to v5.0.2.

Lines 134 and 142 reference v5.0.1 but should match the package version v5.0.2.

📝 Proposed fix
-**Fix**: Fixed in v5.0.1 (`error.issues ?? error.errors ?? []`). Rebuild
+**Fix**: Fixed in v5.0.2 (`error.issues ?? error.errors ?? []`). Rebuild
-**Fix**: Use `path`. v5.0.1 also guards with a clear
+**Fix**: Use `path`. v5.0.2 also guards with a clear

Also applies to: 142-142

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/TESTING_INSTRUCTIONS.md` at line 134, Update the two references of the
package version string "v5.0.1" to "v5.0.2" in the document (the occurrences
noted in the diff), ensuring both instances are changed (including the line
containing "**Fix**: Fixed in v5.0.1 (`error.issues ?? error.errors ?? []`).
Rebuild" and the second occurrence around line 142) so the docs match the
package version.

Comment on lines +107 to +111
if (typeof filePath !== 'string' || filePath.length === 0) {
throw new Error(
'smart_read requires a non-empty "path" argument (received: ' +
`${JSON.stringify(filePath)})`
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle whitespace-only path as invalid input.

Line 107 currently accepts values like " ", so blank-ish input still falls through to a downstream file error instead of the explicit validation error.

Proposed fix
-    if (typeof filePath !== 'string' || filePath.length === 0) {
+    if (typeof filePath !== 'string' || filePath.trim().length === 0) {
       throw new Error(
         'smart_read requires a non-empty "path" argument (received: ' +
           `${JSON.stringify(filePath)})`
       );
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tools/file-operations/smart-read.ts` around lines 107 - 111, The
validation in smart_read currently only rejects non-strings and empty strings
but allows whitespace-only paths; update the check around the filePath variable
in src/tools/file-operations/smart-read.ts so that after confirming typeof
filePath === 'string' you also treat strings with only whitespace as invalid
(e.g., use filePath.trim().length === 0 or a /^\s*$/ test) and throw the same
error; ensure you don't call trim() before the typeof check so you avoid calling
string methods on non-strings and keep the error message thrown by the existing
smart_read validation.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants