{"record":{"id":"7a1c767d95ccf8db","repo":"openai/codex-plugin-cc","slug":"task-activetask-id-is-still-running-use-codex","errorCode":null,"errorMessage":"Task ${activeTask.id} is still running. Use /codex:status before continuing it.","messagePattern":"Task (.+?) is still running\\. Use /codex:status before continuing it\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/codex/scripts/codex-companion.mjs","lineNumber":343,"sourceCode":"    await sleep(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));\n    snapshot = buildSingleJobSnapshot(cwd, reference);\n  }\n\n  return {\n    ...snapshot,\n    waitTimedOut: isActiveJobStatus(snapshot.job.status),\n    timeoutMs\n  };\n}\n\nasync function resolveLatestTrackedTaskThread(cwd, options = {}) {\n  const workspaceRoot = resolveWorkspaceRoot(cwd);\n  const sessionId = getCurrentClaudeSessionId();\n  const jobs = sortJobsNewestFirst(listJobs(workspaceRoot)).filter((job) => job.id !== options.excludeJobId);\n  const visibleJobs = filterJobsForCurrentClaudeSession(jobs);\n  const activeTask = visibleJobs.find((job) => job.jobClass === \"task\" && (job.status === \"queued\" || job.status === \"running\"));\n  if (activeTask) {\n    throw new Error(`Task ${activeTask.id} is still running. Use /codex:status before continuing it.`);\n  }\n\n  const trackedTask = findLatestResumableTaskJob(visibleJobs);\n  if (trackedTask) {\n    return { id: trackedTask.threadId };\n  }\n\n  if (sessionId) {\n    return null;\n  }\n\n  return findLatestTaskThread(workspaceRoot);\n}\n\nasync function executeReviewRun(request) {\n  ensureCodexAvailable(request.cwd);\n  ensureGitRepository(request.cwd);\n","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/openai/codex-plugin-cc/blob/db52e28f4d9ded852ab3942cea316258ae4ef346/plugins/codex/scripts/codex-companion.mjs#L325-L361","documentation":"resolveLatestTrackedTaskThread scans jobs for the workspace, filters to the current Claude session, and finds any task job still in 'queued' or 'running' status. If one exists, resuming is blocked because only one active task per session is allowed (the broker enforces single-flight). The error names the running job id and points to /codex:status.","triggerScenarios":"Calling `task --resume-last` (or any path through resolveLatestTrackedTaskThread) while a previously launched background task has not finished.","commonSituations":"A background task is still running and the user tries to start/resume another; the session filter ties jobs to the current Claude session id (SESSION_ID_ENV).","solutions":["Run /codex:status <job-id> to wait for or inspect the running task.","Cancel the active task with /codex:cancel <job-id> if it is stuck.","Wait for the queued/running task to complete before resuming."],"exampleFix":"// before (task abc123 still running)\ncodex-companion.mjs task --resume-last\n// after\ncodex-companion.mjs status abc123   # wait for completion, then resume","handlingStrategy":"validation","validationCode":"const active = jobs.find(j => j.jobClass === 'task' && (j.status === 'queued' || j.status === 'running'));\nif (active) throw new Error(`Task ${active.id} active`);","typeGuard":"/** @param {object} j @returns {boolean} */\nfunction isTaskActive(j) {\n  return j.jobClass === 'task' && (j.status === 'queued' || j.status === 'running');\n}","tryCatchPattern":null,"preventionTips":["Check /codex:status before launching or resuming tasks.","Cancel stale tasks before starting new ones."],"tags":["concurrency","task","state","single-flight"],"backgroundTag":null,"analyzedSha":"db52e28f4d9ded852ab3942cea316258ae4ef346","analyzedAt":"2026-08-13T05:13:20.855Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}