openai/codex-plugin-cc · error · Error
Claude session source must be a JSONL file: ${sourcePath}
Error message
Claude session source must be a JSONL file: ${sourcePath} What it means
Thrown by resolveClaudeSessionPath when the resolved source path does not have a '.jsonl' extension. Claude transcripts on disk are newline-delimited JSON (.jsonl); any other extension indicates the wrong file was supplied and would fail to parse.
Source
Thrown at plugins/codex/scripts/lib/claude-session-transfer.mjs:28
function resolveUserPath(cwd, value) {
if (value === "~") {
return os.homedir();
}
if (String(value).startsWith("~/")) {
return path.join(os.homedir(), String(value).slice(2));
}
return ensureAbsolutePath(cwd, value);
}
export function resolveClaudeSessionPath(cwd, options = {}) {
const requestedPath = options.source || process.env[TRANSCRIPT_PATH_ENV];
if (!requestedPath) {
throw new Error("Could not identify the current Claude transcript. Retry with --source <path-to-claude-jsonl>.");
}
const sourcePath = resolveUserPath(cwd, requestedPath);
if (path.extname(sourcePath) !== ".jsonl") {
throw new Error(`Claude session source must be a JSONL file: ${sourcePath}`);
}
let source;
let projects;
try {
source = fs.realpathSync(sourcePath);
projects = fs.realpathSync(CLAUDE_PROJECTS_DIR);
} catch {
throw new Error(`Claude session file not found: ${sourcePath}`);
}
const relative = path.relative(projects, source);
if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
throw new Error(`Codex can import Claude sessions only from ${CLAUDE_PROJECTS_DIR}: ${source}`);
}
return source;
}
View on GitHub (pinned to db52e28f4d)
Solutions
- Point --source at the actual Claude '.jsonl' transcript file.
- If you only have a .json export, convert/re-export it to JSONL first.
- Confirm path.extname(source) === '.jsonl' before calling.
- Avoid passing directories; resolve to the specific transcript file.
Example fix
// before
resolveClaudeSessionPath(cwd, { source: '~/session.json' }) // throws
// after
resolveClaudeSessionPath(cwd, { source: '~/.claude/projects/-home-user-proj/session.jsonl' }) Defensive patterns
Strategy: validation
Validate before calling
import path from 'node:path';
function assertJsonl(p) {
if (path.extname(p) !== '.jsonl') {
throw new Error(`Expected a .jsonl transcript, got: ${p}`);
}
}
// call before resolveClaudeSessionPath:
// assertJsonl(options.source); Type guard
function isJsonlPath(p) {
return typeof p === 'string' && p.toLowerCase().endsWith('.jsonl');
} Try / catch
null
Prevention
- Filter file pickers to '*.jsonl' so users cannot select other extensions.
- Convert .json exports to JSONL before importing.
- Validate the extension client-side in any UI that feeds resolveClaudeSessionPath.
- Glob for '*.jsonl' when auto-suggesting transcripts.
When it happens
Trigger: Calling resolveClaudeSessionPath with options.source pointing to a '.json', '.txt', '.log', extensionless file, or a directory. Example: { source: 'session.json' } or { source: '~/transcript.txt' }.
Common situations: User selects a pretty-printed '.json' export instead of the raw '.jsonl' stream. A glob matched the wrong file. The user mistyped the extension or passed a directory.
Related errors
- A Claude session source path is required.
- Unsupported reasoning effort "${effort}". Use one of: none,
- Choose either --enable-review-gate or --disable-review-gate.
- This `/codex:review` target is not supported by the built-in
- Provide a prompt, a prompt file, piped stdin, or use --resum
AI-assisted analysis of openai/codex-plugin-cc@db52e28f4d (2026-08-13).
Data as JSON: /api/errors/69e9d03efb261b7b.
Report an issue: GitHub.