fix(mcp-server): construct default tasks.json path when file parameter not provided#1276
Conversation
…r not provided Resolves issue where MCP tools fail with 'tasksJsonPath is required' error when the 'file' parameter is not provided, even though it should be optional. Changes: - Modified resolveTasksPath() to construct default path /.taskmaster/tasks/tasks.json - Added fallback logic when core path finder returns null - Maintains existing behavior when explicit file path is provided - Added logging for debugging path resolution Fixes #1272 Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com>
🦋 Changeset detectedLatest commit: 79d084d The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughUpdated resolveTasksPath to return a discovered path or, if projectRoot is present and no path is found, construct and return Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Caller
participant PathUtils as resolveTasksPath
participant Finder as coreFindTasksPath
participant Logger as log
Caller->>PathUtils: resolveTasksPath(projectRoot, explicitPath)
alt explicitPath provided
PathUtils->>Finder: coreFindTasksPath(explicitPath, projectRoot)
Finder-->>PathUtils: path or null
PathUtils-->>Caller: path or null
else no explicitPath
alt projectRoot present
PathUtils->>Finder: coreFindTasksPath(null, projectRoot)
Finder-->>PathUtils: foundPath or null
alt foundPath
PathUtils-->>Caller: foundPath
else not found
PathUtils->>Logger: info("Defaulting to {projectRoot}/.taskmaster/tasks/tasks.json")
PathUtils-->>Caller: defaultPath
end
else no projectRoot
PathUtils->>Finder: coreFindTasksPath(null, null)
Finder-->>PathUtils: result (may be null)
PathUtils-->>Caller: result
end
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (4)**/*.js📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
Files:
mcp-server/src/{core/utils,tools}/**/*.js📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
Files:
mcp-server/src/core/utils/path-utils.js📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
Files:
{scripts/modules/utils.js,mcp-server/src/core/utils/path-utils.js,mcp-server/src/tools/utils.js}📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
Files:
🧠 Learnings (11)📚 Learning: 2025-07-18T17:18:17.759ZApplied to files:
📚 Learning: 2025-07-18T17:18:17.759ZApplied to files:
📚 Learning: 2025-07-18T17:11:36.732ZApplied to files:
📚 Learning: 2025-07-18T17:12:57.903ZApplied to files:
📚 Learning: 2025-07-18T05:38:17.352ZApplied to files:
📚 Learning: 2025-07-18T17:07:39.336ZApplied to files:
📚 Learning: 2025-07-18T17:11:36.732ZApplied to files:
📚 Learning: 2025-07-18T17:14:29.399ZApplied to files:
📚 Learning: 2025-07-18T17:11:36.732ZApplied to files:
📚 Learning: 2025-07-18T17:12:57.903ZApplied to files:
📚 Learning: 2025-07-18T17:14:29.399ZApplied to files:
🧬 Code graph analysis (1)mcp-server/src/core/utils/path-utils.js (3)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (1)
Comment |
|
@claude add a changeset inside .changesets please, task-master-ai, patch |
|
Claude finished @Crunchyman-ralph's task —— View job Todo List
✅ Changeset Added SuccessfullyCreated
The changeset has been committed and pushed to the PR branch. This will resolve the changeset bot warning and ensure proper version bumping when the PR is merged. |
Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
mcp-server/src/core/utils/path-utils.js(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.
Files:
mcp-server/src/core/utils/path-utils.js
mcp-server/src/{core/utils,tools}/**/*.js
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within
mcp-server/src/(e.g., path/core logic helpers inmcp-server/src/core/utils/, tool execution/response helpers inmcp-server/src/tools/utils.js).
Files:
mcp-server/src/core/utils/path-utils.js
mcp-server/src/core/utils/path-utils.js
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
Call
findTasksJsonPath(args, log)from within direct function wrappers inmcp-server/src/core/direct-functions/to get the absolute path to the relevanttasks.json.
Files:
mcp-server/src/core/utils/path-utils.js
{scripts/modules/utils.js,mcp-server/src/core/utils/path-utils.js,mcp-server/src/tools/utils.js}
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
{scripts/modules/utils.js,mcp-server/src/core/utils/path-utils.js,mcp-server/src/tools/utils.js}: Keep utilities relevant to their location, export all utility functions in a single statement per file, group related exports together, export configuration constants, do not use default exports, and do not create circular dependencies.
Export all utility functions explicitly, group related functions logically, and include new tagged system utilities.
Files:
mcp-server/src/core/utils/path-utils.js
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/core/utils/path-utils.js : Call `findTasksJsonPath(args, log)` from within direct function wrappers in `mcp-server/src/core/direct-functions/` to get the absolute path to the relevant `tasks.json`.
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/tools/utils.js : Use `normalizeProjectRoot(rawPath, log)`, `getRawProjectRootFromSession(session, log)`, and `withNormalizedProjectRoot(executeFn)` in `mcp-server/src/tools/utils.js` to ensure project root paths are normalized for MCP tools.
Applied to files:
mcp-server/src/core/utils/path-utils.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/core/utils/path-utils.js : Call `findTasksJsonPath(args, log)` from within direct function wrappers in `mcp-server/src/core/direct-functions/` to get the absolute path to the relevant `tasks.json`.
Applied to files:
mcp-server/src/core/utils/path-utils.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.
Applied to files:
mcp-server/src/core/utils/path-utils.js
📚 Learning: 2025-07-18T05:38:17.352Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#943
File: scripts/modules/task-manager/move-task.js:24-24
Timestamp: 2025-07-18T05:38:17.352Z
Learning: In the Claude Task Master system, core task-manager functions are designed with fallback mechanisms for missing projectRoot parameters using the pattern `const projectRoot = providedProjectRoot || findProjectRoot();`. The readJSON and writeJSON functions have default parameters (projectRoot = null, tag = null) and handle missing parameters gracefully. Adding strict validation to these core functions would break the established flexible architecture pattern.
Applied to files:
mcp-server/src/core/utils/path-utils.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
mcp-server/src/core/utils/path-utils.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Applies to mcp-server/src/tools/*.js : MCP server tools in mcp-server/src/tools/*.js must have their execute methods wrapped with the withNormalizedProjectRoot higher-order function from tools/utils.js to ensure consistent path handling.
Applied to files:
mcp-server/src/core/utils/path-utils.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/tools/*.js : All MCP tool execute methods that require access to the project root MUST be wrapped with the withNormalizedProjectRoot Higher-Order Function (HOF) from mcp-server/src/tools/utils.js.
Applied to files:
mcp-server/src/core/utils/path-utils.js
🧬 Code graph analysis (1)
mcp-server/src/core/utils/path-utils.js (2)
src/utils/path-utils.js (8)
defaultPath(343-343)defaultPath(395-395)projectRoot(108-108)projectRoot(197-197)projectRoot(269-269)projectRoot(340-340)projectRoot(386-386)projectRoot(445-445)scripts/modules/utils.js (2)
projectRoot(576-578)projectRoot(671-671)
🪛 GitHub Actions: CI
mcp-server/src/core/utils/path-utils.js
[error] 76-84: Formatter would have printed the following content. Code should be reformatted by the formatter. Run 'biome format .' to fix code style issues.
🔇 Additional comments (1)
mcp-server/src/core/utils/path-utils.js (1)
84-87: Appropriate fallback behavior.The logic correctly handles the case when no
projectRootis available by returning the result ofcoreFindTasksPath(which may be null). The comment clearly explains that without aprojectRoot, a default path cannot be constructed, so null is propagated for upstream error handling. This is the correct behavior.
| const foundPath = coreFindTasksPath(explicitPath, { projectRoot }, log); | ||
| // If core function returns null and no explicit path was provided, | ||
| // construct the expected default path as documented | ||
| if (foundPath === null && !explicitPath) { | ||
| const defaultPath = path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json'); | ||
| log?.info?.(`Core findTasksPath returned null, using default path: ${defaultPath}`); | ||
| return defaultPath; | ||
| } | ||
| return foundPath; |
There was a problem hiding this comment.
🧩 Analysis chain
Fix formatting and use constant for default path.
The code has multiple issues that need attention:
-
Pipeline failure: Biome formatter reports formatting issues on lines 76-84. Run
biome format .to fix. -
Use constant instead of hardcoded path: Line 76 hardcodes
'.taskmaster/tasks/tasks.json', but the codebase uses aTASKMASTER_TASKS_FILEconstant elsewhere (seesrc/utils/path-utils.js:342). Import and use this constant to avoid duplication and ensure consistency. -
Verify downstream handling: The function now returns a potentially non-existent path when
coreFindTasksPathreturns null. Ensure that all calling code (especially inmcp-server/src/core/direct-functions/) can handle paths to files that don't exist yet, or implement file existence validation before returning.
(formatting)
(constant usage)
(downstream handling)
Apply this diff to use the constant (after importing it):
if (projectRoot) {
const foundPath = coreFindTasksPath(explicitPath, { projectRoot }, log);
- // If core function returns null and no explicit path was provided,
- // construct the expected default path as documented
if (foundPath === null && !explicitPath) {
- const defaultPath = path.join(projectRoot, '.taskmaster', 'tasks', 'tasks.json');
+ // Core function returned null; construct the documented default path
+ const defaultPath = path.join(projectRoot, TASKMASTER_TASKS_FILE);
log?.info?.(`Core findTasksPath returned null, using default path: ${defaultPath}`);
return defaultPath;
}
return foundPath;
}Additionally, add this import at the top of the file:
import {
findTasksPath as coreFindTasksPath,
findPRDPath as coreFindPrdPath,
findComplexityReportPath as coreFindComplexityReportPath,
findProjectRoot as coreFindProjectRoot,
- normalizeProjectRoot
+ normalizeProjectRoot,
+ TASKMASTER_TASKS_FILE
} from '../../../../src/utils/path-utils.js';Verify that the constant is exported from src/utils/path-utils.js, or if not available, check src/constants/paths.js:
Verify that direct function wrappers can handle non-existent paths:
🏁 Script executed:
#!/bin/bash
# Description: Verify TASKMASTER_TASKS_FILE constant exists and is exported
# Search for TASKMASTER_TASKS_FILE constant definition
echo "Searching for TASKMASTER_TASKS_FILE constant definition:"
rg -nP --type=js 'TASKMASTER_TASKS_FILE\s*=' src/
# Search for its usage to understand the expected value
echo -e "\nSearching for TASKMASTER_TASKS_FILE usage:"
rg -nP --type=js 'TASKMASTER_TASKS_FILE' src/ -C2
# Check if it's exported from path-utils or constants
echo -e "\nChecking exports:"
rg -nP --type=js 'export.*TASKMASTER_TASKS_FILE' src/Length of output: 2844
🏁 Script executed:
#!/bin/bash
# Description: Check how direct functions handle the tasksJsonPath parameter
# Find direct function files that use findTasksJsonPath or resolveTasksPath
echo "Searching for direct functions that use path resolution:"
rg -nP --type=js 'findTasksJsonPath|resolveTasksPath' mcp-server/src/core/direct-functions/ -C5
# Look for error handling around file operations
echo -e "\nSearching for error handling in direct functions:"
rg -nP --type=js 'readJSON|readFile|existsSync|accessSync' mcp-server/src/core/direct-functions/ -C3Length of output: 12617
Fix formatting, replace hardcoded path with constant, and handle missing default tasks file
- Run
biome format .to resolve formatter errors. - Replace
'.taskmaster/tasks/tasks.json'withTASKMASTER_TASKS_FILEin the fallback logic (imported fromsrc/constants/paths.js). - Ensure direct functions either create the default
.taskmaster/tasks/tasks.jsonor gracefully handle its absence to avoid runtime errors.
🤖 Prompt for AI Agents
In mcp-server/src/core/utils/path-utils.js around lines 72-80, the fallback uses
a hardcoded '.taskmaster/tasks/tasks.json', has formatting issues, and doesn't
handle a missing default tasks file; run `biome format .` to fix formatting,
replace the hardcoded string with the exported TASKMASTER_TASKS_FILE constant
from src/constants/paths.js (add the import if missing), and update the fallback
logic so that either the code creates the default file path (creating parent
directories and an empty tasks file atomically) or returns a well-documented
null/undefined result and logs a clear info/warn so callers can handle the
missing file gracefully.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
.changeset/fix-mcp-default-tasks-path.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.changeset/*.md
📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)
.changeset/*.md: When runningnpm run changesetornpx changeset add, provide a concise summary of the changes for theCHANGELOG.mdin imperative mood, typically a single line, and not a detailed Git commit message.
The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Do not use your detailed Git commit message body as the changeset summary.
Files:
.changeset/fix-mcp-default-tasks-path.md
.changeset/*
📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)
Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Files:
.changeset/fix-mcp-default-tasks-path.md
🧠 Learnings (2)
📚 Learning: 2025-07-17T21:33:57.585Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1002
File: .changeset/puny-friends-give.md:2-3
Timestamp: 2025-07-17T21:33:57.585Z
Learning: In the eyaltoledano/claude-task-master repository, the MCP server code in mcp-server/src/ is part of the main "task-master-ai" package, not a separate "mcp-server" package. When creating changesets for MCP server changes, use "task-master-ai" as the package name.
Applied to files:
.changeset/fix-mcp-default-tasks-path.md
📚 Learning: 2025-09-24T15:12:58.855Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-24T15:12:58.855Z
Learning: Applies to assets/**/.mcp.json : Configure the Task Master MCP server in .mcp.json under mcpServers.task-master-ai using npx task-master-ai and provide required API key env vars
Applied to files:
.changeset/fix-mcp-default-tasks-path.md
🪛 markdownlint-cli2 (0.18.1)
.changeset/fix-mcp-default-tasks-path.md
5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
5-5: Files should end with a single newline character
(MD047, single-trailing-newline)
| "task-master-ai": patch | ||
| --- | ||
|
|
||
| Fix MCP server error when file parameter not provided - now properly constructs default tasks.json path instead of failing with 'tasksJsonPath is required' error. No newline at end of file |
There was a problem hiding this comment.
Rewrite the changeset summary.
Changeset summaries must be a concise, user-facing imperative sentence and the file should end with a trailing newline. Please tighten the copy and add the newline.
Apply this diff:
-Fix MCP server error when file parameter not provided - now properly constructs default tasks.json path instead of failing with 'tasksJsonPath is required' error.
+Fix default tasks.json resolution when the MCP file parameter is omitted.
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Fix MCP server error when file parameter not provided - now properly constructs default tasks.json path instead of failing with 'tasksJsonPath is required' error. | |
| Fix default tasks.json resolution when the MCP file parameter is omitted. | |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
5-5: Files should end with a single newline character
(MD047, single-trailing-newline)
🤖 Prompt for AI Agents
In .changeset/fix-mcp-default-tasks-path.md around line 5, replace the current
descriptive sentence with a concise, user-facing imperative summary such as "Fix
MCP server to construct default tasks.json path when file parameter is missing."
and ensure the file ends with a single trailing newline.
…r not provided (eyaltoledano#1276) Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Fixes eyaltoledano#1272
Resolves issue where MCP tools fail with 'tasksJsonPath is required' error when the 'file' parameter is not provided, even though it should be optional.
Changes
Fixes #1272
Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Improvements