angular/angular-cli · error · Error

Failed to access path: ${fileOrDirPath}

Error message

Failed to access path: ${fileOrDirPath}

What it means

In discoverAndCategorizeFiles, the tool stats the user-supplied path via the virtual file host to decide whether it is a file or directory. If stat() fails (path does not exist or is not readable), the error is wrapped as 'Failed to access path: <path>' with the original error as cause, to be surfaced as a user input error by the caller (the zoneless migration MCP tool).

Source

Thrown at packages/angular/cli/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.ts:129

}

async function discoverAndCategorizeFiles(
  fileOrDirPath: string,
  host: Host,
  extras: ServerContext,
) {
  const filePaths: string[] = [];
  const componentTestFiles = new Set<SourceFile>();
  const filesWithComponents = new Set<SourceFile>();
  const zoneFiles = new Set<SourceFile>();
  const categorizationErrors: { filePath: string; message: string }[] = [];

  let isDirectory: boolean;
  try {
    isDirectory = (await host.stat(fileOrDirPath)).isDirectory();
  } catch (e) {
    // Re-throw to be handled by the main function as a user input error
    throw new Error(`Failed to access path: ${fileOrDirPath}`, { cause: e });
  }

  if (isDirectory) {
    const files = host.glob('**/*.ts', { cwd: fileOrDirPath });
    for await (const file of files) {
      filePaths.push(join(file.parentPath, file.name));
    }
  } else {
    filePaths.push(fileOrDirPath);
    const maybeTestFile = await getTestFilePath(fileOrDirPath, host);
    if (maybeTestFile) {
      // Eagerly add the test file path for categorization.
      filePaths.push(maybeTestFile);
    }
  }

  const CONCURRENCY_LIMIT = 50;
  const filesToProcess = [...filePaths];

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Verify the path exists and is readable (ls the fileOrDirPath) before invoking the tool
  2. Pass an absolute path rooted at the workspace, or run the tool from the correct working directory
  3. Confirm the path is within the MCP server's allowed workspace roots
  4. Check the cause property of the thrown error for the underlying stat failure (ENOENT vs EACCES)

Example fix

// before
await discoverAndCategorizeFiles(host, 'src/app/widget.ts');
// after
import { existsSync, statSync } from 'node:fs';
const p = '/abs/path/src/app/widget.ts';
if (!existsSync(p)) throw new Error(`Path not found: ${p}`);
await discoverAndCategorizeFiles(host, p);
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, statSync } from 'node:fs';
if (!existsSync(fileOrDirPath)) {
  throw new Error(`Path does not exist: ${fileOrDirPath}`);
}
statSync(fileOrDirPath); // also verifies readability

Try / catch

try {
  await discoverAndCategorizeFiles(host, p);
} catch (e) {
  if ((e as Error).message.startsWith('Failed to access path')) {
    console.error(`Check the path exists and is accessible: ${(e as Error & { cause?: Error }).cause?.message}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the zoneless-migration MCP tool with a fileOrDirPath argument that does not exist, is inaccessible due to permissions, or that the virtual host cannot stat. discoverAndCategorizeFiles hits the catch branch at zoneless-migration.ts:129 and re-throws the wrapped Error.

Common situations: Typo in the path passed to the migration tool; relative path resolved against the wrong working directory; path exists on disk but outside the host workspace; deleted or moved directory between planning and running the migration.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/fd6c1e43e2b8cb27. Report an issue: GitHub.