mastra-ai/mastra · info · CreateCancelledError
CreateCancelledError (Operation cancelled)
Error message
CreateCancelledError (Operation cancelled)
What it means
`cancelCreate` in packages/cli/src/commands/create/create.ts:100 prints 'Operation cancelled' via @clack/prompts and throws `CreateCancelledError` (message 'Operation cancelled'). It is the canonical bail-out for user-initiated abandonment of the create flow, raised when SIGINT is received mid-run or when the user cancels an interactive template selection. It signals intentional cancellation, not a failure of the scaffolding itself.
Source
Thrown at packages/cli/src/commands/create/create.ts:102
llmProvider?: CreateLLMProvider;
llmApiKey?: string;
skills?: boolean;
git?: boolean;
template?: string | boolean;
timeout?: number;
analytics?: PosthogAnalytics;
resolveVersionTag?: () => Promise<string | undefined>;
install?: boolean;
}
type PlatformSetupResult =
| { status: 'ready'; token: string; org: { orgId: string; orgName: string } }
| { status: 'cancelled' }
| { status: 'failed'; error: unknown };
function cancelCreate(): never {
p.cancel('Operation cancelled');
throw new CreateCancelledError();
}
async function runCreatePrompt<T>(prompt: (signal: AbortSignal) => Promise<T | symbol>): Promise<T> {
const controller = new AbortController();
let rejectCancellation: (error: CreateCancelledError) => void = () => {};
let cancellationAnnounced = false;
const announceCancellation = () => {
if (cancellationAnnounced) return;
cancellationAnnounced = true;
p.cancel('Operation cancelled');
};
const cancellation = new Promise<never>((_resolve, reject) => {
rejectCancellation = reject;
});
const abort = () => {
controller.abort();
announceCancellation();
rejectCancellation(new CreateCancelledError());View on GitHub (pinned to 75dd419e61)
Solutions
- This is expected behavior — re-run `mastra create` when ready and complete all prompts
- Avoid Ctrl+C during scaffolding; the command cleans up its staging directory automatically
- In scripts, treat CreateCancelledError as a normal exit (the CLI exits without a scary stack) rather than retrying
- Wrap programmatic `create()` calls with isCreateCancelledError to skip error reporting for user cancellations
Example fix
// before
await create(options); // surfaces 'Operation cancelled' as an error
// after
try {
await create(options);
} catch (error) {
if (!isCreateCancelledError(error)) throw error;
// user cancelled — nothing to report
} Defensive patterns
Strategy: try-catch
Type guard
import { isCreateCancelledError } from './commands/create/create';
// or inline:
function isCancel(e: unknown): e is Error {
return e instanceof Error && e.name === 'CreateCancelledError';
} Try / catch
try {
await create(opts);
} catch (error) {
if (isCreateCancelledError(error)) {
process.exitCode = 0; // user cancelled, not a failure
return;
}
throw error;
} Prevention
- Don't send SIGINT to interactive CLI wizards in scripts; pre-answer prompts via flags
- Treat 'Operation cancelled' as a normal exit path in wrappers
- Provide all inputs via CLI args in automation so no prompt can be cancelled
When it happens
Trigger: User presses Ctrl+C (SIGINT) during materialization — the SIGINT handler calls cancelCreate(); user aborts the interactive template picker (resolveTemplate calls cancelCreate when selection is falsy).
Common situations: Developer changes their mind mid-scaffold; slow dependency install prompts a Ctrl+C; accidental Ctrl+C while a prompt is open; CI pipeline aborts and delivers SIGINT to the process.
Related errors
- CreateCancelledError
- Invalid --region "${region}". Expected one of: eu, us.
- ${err instanceof Error ? err.message : String(err)}\nYou can
- No organization matched --org "${value}". Available: ${avail
- Directory ${path.basename(targetPath)} already exists
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d1b5737c3c5fefc3.
Report an issue: GitHub.