mastra-ai/mastra · error
Invalid checkpoint name: ${name}
Error message
Invalid checkpoint name: ${name} What it means
LocalSandbox._checkpointPath() resolves the on-disk directory for a named checkpoint and rejects unsafe names. A valid name starts with an alphanumeric character and contains only [A-Za-z0-9._-], and may not contain `..` anywhere. This prevents path traversal via checkpoint names when they're joined into the checkpoints directory.
Source
Thrown at packages/core/src/workspace/sandbox/local-sandbox.ts:405
this._seatbeltProfilePath = path.join(this._sandboxFolderPath, `seatbelt-${configHash}.sb`);
await fs.writeFile(this._seatbeltProfilePath, generatedProfile, 'utf-8');
}
}
this.logger.debug('Sandbox started', { workingDirectory: this.workingDirectory });
}
// ---------------------------------------------------------------------------
// Checkpoints
// ---------------------------------------------------------------------------
/** LocalSandbox persists real filesystem-backed checkpoints. */
readonly supportsCheckpoints = true;
/** Resolve the on-disk directory for a named checkpoint, rejecting unsafe names. */
private _checkpointPath(name: string): string {
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) || name.includes('..')) {
throw new Error(`Invalid checkpoint name: ${name}`);
}
return path.join(this._checkpointsDirectory, name);
}
/**
* Seed an empty/missing working directory from the configured checkpoint.
* Missing checkpoint or already-populated workdir → no-op (normal start).
*/
private async _seedFromCheckpoint(): Promise<void> {
if (!this._checkpointName && !this._seedCheckpointName) return;
// Only seed an empty working directory; a populated one wins.
const entries = await fs.readdir(this.workingDirectory).catch(() => []);
if (entries.length > 0) return;
// Prefer the primary checkpoint; fall back to the boot-only seed checkpoint.
const candidates = [this._checkpointName, this._seedCheckpointName].filter(
(name): name is string => name !== undefined,View on GitHub (pinned to 75dd419e61)
Solutions
- Sanitize the name to the allowed pattern: /^[A-Za-z0-9][A-Za-z0-9._-]*$/ (no slashes, spaces, or `..`)
- Derive names programmatically, e.g. slugify or Date.now()-based names like `cp-1724912345`
- Validate before calling any checkpoint API and show a clear message to the user when their input is invalid
Example fix
// before sandbox.checkpointDir(featureBranchName); // 'feat/my-branch' throws // after const safeName = 'cp-' + featureBranchName.replace(/[^A-Za-z0-9._-]/g, '-').replace(/^[^A-Za-z0-9]/, 'x'); sandbox.checkpointDir(safeName);
Defensive patterns
Strategy: validation
Validate before calling
export function toSafeCheckpointName(raw: string): string {
const name = raw.replace(/[^A-Za-z0-9._-]/g, '-').replace(/\.+/g, '.').replace(/^[^A-Za-z0-9]/, 'x');
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) || name.includes('..')) throw new Error(`Invalid checkpoint name: ${raw}`);
return name;
} Try / catch
try {
const dir = sandbox.checkpointDir(name);
} catch (err) {
if (/Invalid checkpoint name/.test(String(err?.message))) {
throw new Error(`Checkpoint names must match [A-Za-z0-9][A-Za-z0-9._-]*; got: ${name}`);
}
throw err;
} Prevention
- Generate checkpoint names programmatically (timestamps/uuids) instead of from free-form user input
- Slugify branch or feature names before using them as checkpoint names
- Share one sanitizing helper across all checkpoint call sites so the pattern is enforced once
When it happens
Trigger: Calling checkpoint-related APIs (checkpointDir, target, restore flows) with a name like `../../etc`, `my checkpoint` (space), `#draft`, an empty string, or any name with slashes/unicode.
Common situations: Generating checkpoint names from user input, branch names, or timestamps containing `/` or spaces; using identifiers with `#` or `:`; forgotten sanitization when checkpoint names come from API consumers.
Related errors
- Invalid route path: "${path}". Path cannot contain '..', '?'
- Worker ${label} must stay within the deployed artifact root.
- ${label} escapes workspace
- Path escapes workspace
- Invalid resourceId: ${resourceId}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/8896ff71ef777645.
Report an issue: GitHub.