vercel/ai · error · Error
Invalid Cline history file name: ${input.historyFileName}
Error message
Invalid Cline history file name: ${input.historyFileName} What it means
resolveContainedSandboxPath validates that a Cline history file name resolves to a file inside the history directory. It computes path.posix.relative(historyDir, filePath) and throws if the result is empty (points at the directory itself), starts with '..' (escapes the directory), or is absolute. This prevents path-traversal or out-of-sandbox access when reading Cline resume history.
Source
Thrown at packages/harness-cline/src/cline-resume-state.ts:83
return privateSessionDir;
}
function resolveContainedSandboxPath(input: {
readonly privateSessionDir: string;
readonly historyFileName: string;
}): string {
const historyDir = path.posix.resolve(input.privateSessionDir);
const filePath = path.posix.resolve(
historyDir,
safeClineHistoryFileName(input.historyFileName),
);
const relativePath = path.posix.relative(historyDir, filePath);
if (
relativePath === '' ||
relativePath.startsWith('..') ||
path.posix.isAbsolute(relativePath)
) {
throw new Error(
`Invalid Cline history file name: ${input.historyFileName}`,
);
}
return filePath;
}
/**
* Persist the runtime's conversation history into private sandbox state so a
* future process can resume the session after
* `HarnessV1SandboxProvider.resume?.({ sessionId })` reattaches the sandbox.
*/
export async function persistHistoryToSandbox(args: {
readonly sandbox: Experimental_SandboxSession;
readonly privateSessionDir: string;
readonly historyFileName: string;
readonly messages: readonly AgentMessage[];
readonly abortSignal?: AbortSignal;
}): Promise<void> {View on GitHub (pinned to 69428b1f8b)
Solutions
- Pass only the bare file name (e.g. 'task-123.json'), not a path, and let the harness join it with the history directory.
- Sanitize the input: strip directory components and reject names containing '/', '..', or leading separators before calling the API.
- If the history file lives elsewhere, point the history directory configuration at its actual parent directory instead of using a relative name.
Example fix
// before
resolveClineResumeState({ historyFileName: `../../tasks/${taskId}.json` });
// after
if (!/^[A-Za-z0-9._-]+$/.test(taskId)) throw new Error('bad task id');
resolveClineResumeState({ historyFileName: `${taskId}.json` }); Defensive patterns
Strategy: validation
Validate before calling
function isValidHistoryFileName(name: string): boolean {
return /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name) && !name.startsWith('.') && !name.includes('/') && !path.posix.isAbsolute(name);
}
if (!isValidHistoryFileName(historyFileName)) throw new Error(`Refusing unsafe history file name: ${historyFileName}`); Try / catch
try {
await resolveClineResumeState({ historyFileName });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid Cline history file name')) {
historyFileName = path.posix.basename(historyFileName);
// retry or surface a user-facing validation error
} else throw e;
} Prevention
- Never construct history file names from raw user input; whitelist a strict character set.
- Always pass a bare file name, never a path, to resume-state APIs.
- Reject names containing '/', '\\', '..', or absolute prefixes in your own input layer.
When it happens
Trigger: Calling the resume-state API with historyFileName such as '../other-task.json', '/etc/passwd', an absolute path, an empty name, or a name that normalizes to the history directory itself (e.g. '.' or a nested path like 'a/../../x').
Common situations: Storing or deriving history file names from user input or task IDs without sanitizing; joining a history file name with the wrong base directory; migrating from an older Cline state layout where file names included subdirectories or absolute paths.
Related errors
- Invalid Cline history file name: ${historyFileName}
- Invalid Pi ${label} name: ${name}
- Tool approval signature verification failed for approval "${
- ACP runtime environment key ${JSON.stringify(key)} cannot be
- Cline MCP server ${JSON.stringify(input.serverName)} must de
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/429e6eaf18f54c14.
Report an issue: GitHub.