{"record":{"id":"1797ff9088ed923b","repo":"Yeachan-Heo/oh-my-codex","slug":"question-record-not-found-recordpath","errorCode":null,"errorMessage":"Question record not found: ${recordPath}","messagePattern":"Question record not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/question/state.ts","lineNumber":129,"sourceCode":"  const recordPath = getQuestionRecordPath(cwd, questionId, sessionId);\n  await writeQuestionRecord(recordPath, record);\n  if (options.emitEvent) {\n    await appendQuestionEvent(cwd, 'question-created', record, {\n      recordPath,\n      timeoutMs: options.timeoutMs,\n      runId: options.runId,\n      now,\n    });\n  }\n  return { recordPath, record };\n}\n\nexport async function updateQuestionRecord(\n  recordPath: string,\n  updater: (record: QuestionRecord) => QuestionRecord,\n): Promise<QuestionRecord> {\n  const current = await readQuestionRecord(recordPath);\n  if (!current) throw new Error(`Question record not found: ${recordPath}`);\n  const updated = updater(current);\n  await writeQuestionRecord(recordPath, updated);\n  return updated;\n}\n\nexport async function markQuestionPrompting(\n  recordPath: string,\n  renderer: QuestionRendererState,\n  options: { closeQuestionRenderer?: CloseQuestionRenderer } = {},\n): Promise<QuestionRecord> {\n  return await withQuestionSubmitLock(recordPath, async () => {\n    let rendererToClose: QuestionRendererState | undefined;\n    const updated = await updateQuestionRecord(recordPath, (record) => {\n      if (isTerminalQuestionStatus(record.status)) {\n        rendererToClose = renderer;\n        return record;\n      }\n      return {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/question/state.ts#L111-L147","documentation":"updateQuestionRecord reads the question record file before applying an updater; if readQuestionRecord returns null (file missing, unreadable, or unparseable into a record) it throws this error. The API refuses to 'update' a record that does not exist, mirroring a read-modify-write on a missing file.","triggerScenarios":"Calling updateQuestionRecord (or higher-level updated/markQuestionTerminalError) with a recordPath that was deleted, never created, or contains invalid JSON; concurrent deletion by another process between creation and update.","commonSituations":"Record file cleaned up by a sweeper/expiry while an answer was in flight; wrong path passed (typo, wrong session dir); crash after partial write leaving corrupt JSON; tests that mock the filesystem incompletely.","solutions":["Verify the record file exists and parses before calling update (readQuestionRecord !== null)","Re-check lifecycle: ensure the record is created before any update call and not deleted by a concurrent cleanup job","If racing with cleanup, serialize via the provided submit lock so cleanup cannot interleave","Handle the error by recreating the record or surfacing 'question not found' to the user instead of retrying blindly"],"exampleFix":"// before\nawait updateQuestionRecord(path, (r) => ({ ...r, status: 'answered' }));\n// after\nif (!(await readQuestionRecord(path))) {\n  throw new Error(`question ${path} no longer exists; it may have expired`);\n}\nawait updateQuestionRecord(path, (r) => ({ ...r, status: 'answered' }));","handlingStrategy":"validation","validationCode":"const current = await readQuestionRecord(recordPath);\nif (!current) throw new Error('record missing — recreate or report expired question');","typeGuard":null,"tryCatchPattern":"try { await updateQuestionRecord(p, fn); } catch (e) { if (/Question record not found/.test((e as Error).message)) { await handleExpiredQuestion(p); return; } throw e; }","preventionTips":["Create the record before scheduling any update","Guard cleanup jobs so they don't delete records with pending operations","Pass the exact recordPath returned by the create API"],"tags":["state-file","read-modify-write","question-record"],"backgroundTag":"file-not-found","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}