angular/angular-cli · error · CommandModuleError
Repository is not clean. Please commit or stash any changes
Error message
Repository is not clean. Please commit or stash any changes before updating.
What it means
Before updating packages, the update command checks git cleanliness with checkCleanGit(context.root). If there are packages to install and the working tree is dirty, and --allow-dirty was not passed, it aborts with a CommandModuleError so update/migration changes won't mix with uncommitted work.
Source
Thrown at packages/angular/cli/src/commands/update/cli.ts:146
.middleware((argv) => {
if (argv.name) {
argv['migrate-only'] = true;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return argv as any;
})
.check(({ packages, 'allow-dirty': allowDirty, 'migrate-only': migrateOnly }) => {
const { logger } = this.context;
// This allows the user to easily reset any changes from the update.
if (packages?.length && !checkCleanGit(this.context.root)) {
if (allowDirty) {
logger.warn(
'Repository is not clean. Update changes will be mixed with pre-existing changes.',
);
} else {
throw new CommandModuleError(
'Repository is not clean. Please commit or stash any changes before updating.',
);
}
}
if (migrateOnly) {
if (packages?.length !== 1) {
throw new CommandModuleError(
`A single package must be specified when using the 'migrate-only' option.`,
);
}
}
return true;
})
.strict();
}
View on GitHub (pinned to bb72145f9a)
Solutions
- Commit or stash all changes, then rerun `ng update ...`.
- Pass --allow-dirty if you intentionally want to mix changes (warned but allowed).
- In CI, ensure a clean checkout (no patching of package.json/lockfile before ng update).
Example fix
// before git status -s # M package.json ng update @angular/core // after git add -A && git commit -m "wip" ng update @angular/core # or: ng update @angular/core --allow-dirty
Defensive patterns
Strategy: validation
Validate before calling
import { execSync } from 'child_process';
const dirty = execSync('git status --porcelain', { cwd: repoRoot }).toString().trim();
if (dirty && !allowDirty) {
throw new Error('Commit or stash changes before running ng update');
} Try / catch
try {
await ngUpdate(packages);
} catch (e) {
if (String(e.message).includes('Repository is not clean')) {
execSync('git stash', { cwd: repoRoot });
await ngUpdate(packages);
execSync('git stash pop', { cwd: repoRoot });
} else throw e;
} Prevention
- Make `git status --porcelain` a preflight step in update scripts.
- Commit or stash WIP before dependency upgrades.
- Use --allow-dirty only in disposable CI environments.
When it happens
Trigger: Running `ng update <package>` with modified/untracked files in the repository without --allow-dirty; checkCleanGit returns false for the workspace root.
Common situations: Forgetting to commit before updating; CI checkouts with generated files or modified lockfiles; local WIP during dependency upgrades.
Related errors
- A single package must be specified when using the 'migrate-o
- Unable to install packages
- Incompatible peer dependencies found. See above for details.
- Package ${JSON.stringify(name)} was not found in package.jso
- Package ${name} is not installed.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/682b6c12f5b26841.
Report an issue: GitHub.