slopus/happy · error
Happy session ${session.id} is missing its Codex thread ID.
Error message
Happy session ${session.id} is missing its Codex thread ID. What it means
buildResumeLaunch throws this when a session's resolved flavor is 'codex' but its persisted metadata lacks codexThreadId. Resuming a Codex session requires the original thread ID to pass to `codex --resume <thread-id>`; without it the CLI cannot reconstruct the session.
Source
Thrown at packages/happy-cli/src/resume/handleResumeCommand.ts:59
}
function resolveFlavor(metadata: Metadata): 'codex' | 'claude' | null {
if (metadata.flavor === 'codex' || metadata.codexThreadId) {
return 'codex';
}
if (metadata.flavor === 'claude' || metadata.claudeSessionId) {
return 'claude';
}
return null;
}
export function buildResumeLaunch(session: ResumableHappySession, options: ResumeLaunchOptions = {}): ResumeLaunch {
const { metadata } = session;
const flavor = resolveFlavor(metadata);
if (flavor === 'codex') {
if (!metadata.codexThreadId) {
throw new Error(`Happy session ${session.id} is missing its Codex thread ID.`);
}
const args = ['codex', '--resume', metadata.codexThreadId];
if (options.startedBy) {
args.push('--started-by', options.startedBy);
}
return {
cwd: metadata.path,
args,
};
}
if (flavor === 'claude') {
if (!metadata.claudeSessionId) {
throw new Error(`Happy session ${session.id} is missing its Claude session ID.`);
}
const args = ['claude'];
if (options.claudeStartingMode) {
args.push('--happy-starting-mode', options.claudeStartingMode);View on GitHub (pinned to b824cd0a46)
Solutions
- Start a new Happy session with the current CLI version so codexThreadId is captured in metadata
- Check that the session was genuinely started with Codex support enabled in the installed happy-cli version
- Upgrade happy-cli and re-sync/re-encrypt the session metadata if your version predates codexThreadId
- Resume the session manually with `codex --resume <thread-id>` if you can find the thread ID under ~/.codex
Defensive patterns
Strategy: validation
Validate before calling
function canResumeCodex(s: ResumableHappySession): boolean {
return resolveFlavor(s.metadata) === 'codex' && typeof s.metadata.codexThreadId === 'string' && s.metadata.codexThreadId.length > 0;
} Type guard
function hasCodexThreadId(m: Metadata): m is Metadata & { codexThreadId: string } {
return typeof (m as any).codexThreadId === 'string' && (m as any).codexThreadId.length > 0;
} Try / catch
try {
const launch = buildResumeLaunch(session);
} catch (e) {
if (e instanceof Error && e.message.includes('missing its Codex thread ID')) {
console.error('This Codex session cannot be resumed; start a new session with an up-to-date CLI.');
return;
}
throw e;
} Prevention
- Keep happy-cli up to date so codexThreadId is always captured
- Check metadata.codexThreadId before attempting resume of a codex-flavored session
- Avoid hand-editing encrypted session metadata
- Re-create very old Codex sessions with the current CLI
When it happens
Trigger: Calling buildResumeLaunch (directly or via handleResumeCommand/launch) with a ResumableHappySession whose metadata.flavor resolves to 'codex' while metadata.codexThreadId is undefined/null — e.g. metadata was written by an older CLI version before Codex support recorded thread IDs.
Common situations: Sessions created before a Codex-supporting happy release; metadata encrypted before codexThreadId was added to ResumableMetadataSchema; hand-edited or partially synced sessions file; session started via a path that never captured the Codex thread ID.
Related errors
- Happy session ${session.id} is missing its Claude session ID
- Failed to resume Codex thread ${opts.threadId}: ${reason}
- Happy session ${sessionId} is missing resumable metadata.
- The chosen rewind point is no longer present in the source C
- Metadata version mismatch
AI-assisted analysis of slopus/happy@b824cd0a46 (2026-08-31).
Data as JSON: /api/errors/c74d4565d3acde39.
Report an issue: GitHub.