{"record":{"id":"61c5cda6257844d6","repo":"mastra-ai/mastra","slug":"failed-to-create-directory-errormessage","errorCode":null,"errorMessage":"Failed to create directory: ${errorMessage}","messagePattern":"Failed to create directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/scorers/file-utils.ts","lineNumber":18,"sourceCode":"import fs from 'node:fs';\nimport path from 'node:path';\nimport * as p from '@clack/prompts';\n\nconst DEFAULT_SCORERS_DIR = 'src/mastra/scorers';\n\nexport function writeScorer(filename: string, content: string, customPath?: string): { ok: true; message: string } {\n  const rootDir = process.cwd();\n  const scorersPath = customPath || DEFAULT_SCORERS_DIR;\n  const fullPath = path.join(rootDir, scorersPath);\n\n  if (!fs.existsSync(fullPath)) {\n    try {\n      fs.mkdirSync(fullPath, { recursive: true });\n      p.log.success(`Created scorers directory at ${scorersPath}`);\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      throw new Error(`Failed to create directory: ${errorMessage}`);\n    }\n  }\n\n  const filePath = path.join(fullPath, filename);\n\n  if (fs.existsSync(filePath)) {\n    throw new Error(`Skipped: Scorer ${filename} already exists at ${scorersPath}`);\n  }\n\n  try {\n    fs.writeFileSync(filePath, content);\n\n    return { ok: true, message: `Created scorer at ${path.relative(rootDir, filePath)}` };\n  } catch (error) {\n    const errorMessage = error instanceof Error ? error.message : String(error);\n    throw new Error(`Failed to write scorer: ${errorMessage}`);\n  }\n}","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/scorers/file-utils.ts#L1-L36","documentation":"`writeScorer` wraps any failure from fs.mkdirSync when creating the scorers output directory. The underlying OS error (e.g. EACCES, ENOSPC, ENOTDIR) is embedded in the message. It means the CLI could not create the directory where the generated scorer file should live.","triggerScenarios":"Running the scorer add/generate command when the target path does not exist and mkdirSync fails — typically due to insufficient write permissions, a path component that is a file, or read-only filesystem.","commonSituations":"Scorers path collides with an existing file named `scorers`; running in a sandbox/container without write access to the project root; disk full.","solutions":["Check write permissions on the target directory (ls -la) and fix with chmod/chown","Ensure no regular file exists at the scorers path that blocks directory creation","Free disk space if ENOSPC","Create the directory manually with mkdir -p and rerun"],"exampleFix":"// before\n# scorers path occupied by a file\nscorers  (regular file)\n// after\nrm scorers && mkdir -p scorers","handlingStrategy":"try-catch","validationCode":"import { statSync, existsSync } from 'node:fs';\nif (existsSync(scorersPath) && !statSync(scorersPath).isDirectory()) {\n  throw new Error(`${scorersPath} exists and is not a directory`);\n}\naccessSync(dirname(scorersPath), constants.W_OK);","typeGuard":"const canWrite = (p: string): boolean => {\n  try { accessSync(p, constants.W_OK); return true; } catch { return false; }\n};","tryCatchPattern":"try {\n  await writeScorer({ ... });\n} catch (e) {\n  const msg = (e as Error).message;\n  if (msg.startsWith('Failed to create directory')) {\n    console.error('Check permissions/disk space for the scorers path:', msg);\n  } else throw e;\n}","preventionTips":["Ensure the project directory is writable by your user","Never name a regular file `scorers` in the project root","Check disk space in CI containers","Avoid running CLI tools under restrictive users/roots"],"tags":["filesystem","permissions","cli","directory"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}