{"record":{"id":"0077005ed38955ac","repo":"eyaltoledano/claude-task-master","slug":"invalid-input","errorCode":"INVALID_INPUT","errorMessage":"Project path must be an absolute path, received: \"${options.projectPath}\"","messagePattern":"Project path must be an absolute path, received: \"(.+?)\"","errorType":"error_code","errorClass":"TaskMasterError","httpStatus":null,"severity":"error","filePath":"packages/tm-core/src/tm-core.ts","lineNumber":148,"sourceCode":"\t}\n\n\tprivate _options: TmCoreOptions;\n\n\t/**\n\t * Private constructor - use TmCore.create() instead\n\t * This ensures TmCore is always properly initialized\n\t */\n\tprivate constructor(options: TmCoreOptions) {\n\t\tif (!options.projectPath) {\n\t\t\tthrow new TaskMasterError(\n\t\t\t\t'Project path is required',\n\t\t\t\tERROR_CODES.MISSING_CONFIGURATION\n\t\t\t);\n\t\t}\n\n\t\t// Validate that projectPath is absolute\n\t\tif (!path.isAbsolute(options.projectPath)) {\n\t\t\tthrow new TaskMasterError(\n\t\t\t\t`Project path must be an absolute path, received: \"${options.projectPath}\"`,\n\t\t\t\tERROR_CODES.INVALID_INPUT\n\t\t\t);\n\t\t}\n\n\t\t// Normalize the path\n\t\tthis._projectPath = path.resolve(options.projectPath);\n\t\tthis._options = options;\n\t\t// Domain facades will be initialized in initialize()\n\t}\n\n\t/**\n\t * Initialize the TmCore instance\n\t * Private - only called by the factory method\n\t */\n\tprivate async initialize(): Promise<void> {\n\t\ttry {\n\t\t\t// Initialize logger first (before anything else that might log)","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/tm-core.ts#L130-L166","documentation":"TmCore's constructor requires projectPath to be an absolute filesystem path. Relative paths (or values like '.', '~/proj', or URLs) are rejected with a TaskMasterError code INVALID_INPUT, because downstream modules resolve all project files against this path and need it unambiguous.","triggerScenarios":"Calling TmCore.create({ projectPath: '.' }) or with relative paths like './myproject', or with tilde-prefixed paths like '~/projects/app' that Node does not expand.","commonSituations":"Passing CLI/user input straight through without resolution, reusing a relative path from package.json scripts, or tilde paths from shell-style config files.","solutions":["Resolve to absolute before creating: path.resolve(projectPath) in the current working directory context.","Expand tilde manually: projectPath.startsWith('~/') ? path.join(os.homedir(), projectPath.slice(1)) : projectPath.","Log/echo the final absolute path so users can see what is being used."],"exampleFix":"// before\nconst tmCore = await TmCore.create({ projectPath: userPath }); // e.g. '~/proj'\n// after\nconst resolved = userPath.startsWith('~')\n  ? path.join(os.homedir(), userPath.slice(1))\n  : path.resolve(userPath);\nconst tmCore = await TmCore.create({ projectPath: resolved });","handlingStrategy":"validation","validationCode":"const path = require('node:path');\nif (!path.isAbsolute(projectPath)) {\n  projectPath = path.resolve(projectPath);\n}","typeGuard":"const path = require('node:path');\nfunction isAbsolutePath(p) {\n  return typeof p === 'string' && path.isAbsolute(p);\n}","tryCatchPattern":"try {\n  const tmCore = await TmCore.create({ projectPath });\n} catch (e) {\n  if (e instanceof TaskMasterError && e.code === 'INVALID_INPUT') {\n    console.error(`projectPath must be absolute; got ${JSON.stringify(e.message)}`);\n  } else throw e;\n}","preventionTips":["Run path.resolve() on every user-supplied path before create().","Expand ~ with os.homedir() — Node does not expand tildes.","Store absolute paths in saved config files."],"tags":["configuration","validation","path"],"backgroundTag":"invalid-path-argument","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}