nocobase/nocobase · warning
Refusing to remove ${label} at "${resolved}" because it is t
Error message
Refusing to remove ${label} at "${resolved}" because it is too broad. What it means
assertSafeRemovalPath (packages/core/cli/src/commands/app/shared.ts, used by removePathIfExists) resolves the target path and rejects removal if it equals the filesystem root, the current working directory, or the user's home directory, throwing 'Refusing to remove <label> at "<resolved>" because it is too broad.' This is a safety guard against catastrophic rm -rf of critical directories during app cleanup.
Source
Thrown at packages/core/cli/src/commands/app/shared.ts:37
type RemovePathOptions = {
retryCommand?: string;
};
type NodeFileSystemError = Error & {
code?: unknown;
};
export function resolveConfiguredPath(value: unknown): string | undefined {
return resolveConfiguredEnvPath(value);
}
function assertSafeRemovalPath(target: string, label: string): void {
const resolved = path.resolve(target);
const cwd = path.resolve(process.cwd());
const home = path.resolve(os.homedir());
const root = path.parse(resolved).root;
if (resolved === root || resolved === cwd || resolved === home) {
throw new Error(`Refusing to remove ${label} at "${resolved}" because it is too broad.`);
}
}
function getErrorCode(error: unknown): string | undefined {
if (!(error instanceof Error)) {
return undefined;
}
const { code } = error as NodeFileSystemError;
return typeof code === 'string' ? code : undefined;
}
function isPermissionDeniedError(error: unknown): boolean {
const code = getErrorCode(error);
return code === 'EACCES' || code === 'EPERM';
}
function formatOriginalError(error: unknown): string {
const message = error instanceof Error ? error.message : String(error);View on GitHub (pinned to fa42722fef)
Solutions
- Fix the path configuration so the cleanup target is the specific app directory (e.g. ~/.nocobase/apps/<name>), not its parent.
- Ensure the CLI is run from the intended working directory, since CWD itself is protected.
- Check the app env config for empty or '.' values for dir/storage/data paths before destroy.
- If you truly need to remove a broad directory, do it manually with explicit rm -rf of the precise path after verifying contents.
Example fix
// before (config) APP_ROOT= # falls back to '.', 'too broad' error // after APP_ROOT=~/.nocobase/apps/myapp
Defensive patterns
Strategy: validation
Validate before calling
import path from 'path';
import os from 'os';
function isSafeRemovalPath(target: string): boolean {
const resolved = path.resolve(target);
const protectedPaths = [path.parse(resolved).root, path.resolve(process.cwd()), path.resolve(os.homedir())];
return !protectedPaths.includes(resolved);
}
if (!isSafeRemovalPath(cleanupPath)) throw new Error(`Refusing cleanup: ${cleanupPath} resolves to a protected directory; fix the app path config`); Type guard
function isSpecificAppPath(target: string): boolean {
const resolved = path.resolve(target);
return resolved.split(path.sep).filter(Boolean).length >= 3 && resolved.startsWith(path.resolve(os.homedir(), '.nocobase'));
} Try / catch
try {
await removePathIfExists(dir, { label: 'app dir' });
} catch (error) {
if ((error as Error).message.includes('because it is too broad')) {
console.error(`Cleanup target ${(error as Error).message.match(/at "(.*)"/)?.[1]} is protected — correct the app path configuration instead of overriding.`);
} else throw error;
} Prevention
- Never leave app path / storage / data config values empty or set to '.' or '~'.
- Point all directory config at explicit per-app subdirectories (e.g. ~/.nocobase/apps/<name>).
- Avoid running destroy from inside the directory being removed (CWD is protected and commands may misbehave).
- Print resolved paths in a dry-run before enabling destructive cleanup in scripts.
When it happens
Trigger: Calling removePathIfExists (e.g. during `app destroy` cleanup of app dir / data / storage paths) when the configured path variable points at /, the CWD, or $HOME — typically because a path config is empty, '.', unset, or wrongly set to home.
Common situations: App env config with an empty/missing app root so the cleanup target falls back to '.' or '/'; users setting storage/data directories to ~; misconfigured DEST/APP_ROOT env vars; running the CLI from inside the directory meant to be removed.
Related errors
- Refusing to destroy current env "${envName}" without explici
- Refusing to destroy env "${envName}" without confirmation in
- Invalid license key format
- License key not match current environment
- Please create .env.e2e file first!
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/c319d8a140f3d30c.
Report an issue: GitHub.