{"record":{"id":"ba091cdf7d9393c6","repo":"coleam00/Archon","slug":"workflow-source-legacy-live","errorCode":"workflow.source_legacy_live","errorMessage":"⚠️ This run started before Archon captured workflow source, so there is nothing recorded to resume from. Continuing against the current source on disk, which may differ from what the run originally executed.","messagePattern":"⚠️ This run started before Archon captured workflow source, so there is nothing recorded to resume from\\. Continuing against the current source on disk, which may differ from what the run originally executed\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/workflows/src/executor.ts","lineNumber":2655,"sourceCode":"      // would re-read `commands.folder` and `defaults:` from the workspace it acts on and\n      // reinterpret the frozen bytes through them.\n      workflowSourceRoots = capturedSourceRoots(recordedSource.root, loaded.manifest.source_config);\n      getLog().debug(\n        { workflowRunId: workflowRun.id, captureRoot: recordedSource.root },\n        'workflow.source_restored'\n      );\n    } catch (error) {\n      return await failRunOnSource(\n        `This run's captured workflow source at ${recordedSource.root} is missing or altered ` +\n          `(${(error as Error).message}). The run cannot be resumed against different source; ` +\n          'start a fresh run to execute the current workflow.'\n      );\n    }\n  } else if (isResume) {\n    // Created before source capture existed. Its original bytes were never recorded and\n    // cannot be reconstructed, so it resumes the way it always did — against live source.\n    // This is the ONLY warning-and-continue path, and it retires with those runs.\n    getLog().warn({ workflowRunId: workflowRun.id }, 'workflow.source_legacy_live');\n    await safeSendMessage(\n      platform,\n      conversationId,\n      '⚠️ This run started before Archon captured workflow source, so there is nothing ' +\n        'recorded to resume from. Continuing against the current source on disk, which may ' +\n        'differ from what the run originally executed.'\n    );\n  } else if (preparedSource) {\n    // The normal fresh path: the caller captured BEFORE selecting a workflow and\n    // discovered from that capture, so the YAML being executed and the commands and\n    // scripts beside it are one consistent set of bytes.\n    //\n    // Move the staged capture under this run's artifacts, so it lives and dies with the\n    // rest of the run's output instead of accumulating in a staging directory nothing\n    // reclaims. Same filesystem, so this is a rename.\n    const finalCaptureRoot = getRunSourceCapturePath(artifactsDir);\n    try {\n      if (preparedSource.captureRoot !== finalCaptureRoot) {","sourceCodeStart":2637,"sourceCodeEnd":2673,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/workflows/src/executor.ts#L2637-L2673","documentation":"Current Archon captures the workflow YAML source at run start and resumes from those recorded bytes. Runs created before source capture existed have no recorded bytes, so on resume the executor warns and continues against the current file on disk, which may differ from what the run originally executed. This is the only warning-and-continue resume path and retires once legacy runs are gone.","triggerScenarios":"Any resume (isResume) of a workflow run persisted before source capture was introduced, i.e. the run record carries no captured workflow source; fires on executor.ts:2655 for CLI, chat, and web resume alike.","commonSituations":"Installations upgraded across the source-capture release with runs paused since before the upgrade; operators resume a weeks-old paused run after the workflow file was edited, so the resumed execution silently differs from the original.","solutions":["Review the current workflow file on disk and confirm it still matches the original run's intent before letting the resume proceed; revert incompatible edits.","If fidelity matters, cancel/fail the legacy run and start a fresh run — new runs capture their source and resume faithfully.","If divergence is acceptable, acknowledge the warning and let the resume continue against live source.","As an upgrade task, sweep for runs lacking captured source and close them out so this path retires."],"exampleFix":"# before: blindly resuming the legacy run (executes current on-disk YAML)\n$ archon workflow resume <legacyRunId>\n# after: start a fresh run whose source is captured and resumes are faithful\n$ archon workflow run <workflowName> ...","handlingStrategy":"validation","validationCode":"// Detect a legacy run before resuming and decide whether fidelity matters:\nconst run = await store.getWorkflowRun(runId);\nif (!run.workflowSource) {\n  console.warn('Legacy run: no captured source; resume will use live on-disk YAML');\n  // diff the current file against the known-original semantics, or start a new run\n}","typeGuard":"function hasCapturedSource(run: { workflowSource?: string | null }): run is { workflowSource: string } {\n  return typeof run.workflowSource === 'string' && run.workflowSource.length > 0;\n}","tryCatchPattern":null,"preventionTips":["After upgrading, close out or restart long-paused runs created before source capture.","Don't edit a workflow's YAML while a legacy run is paused and expected to resume.","Prefer starting a fresh run over resuming pre-capture runs when exact semantics matter.","Sweep for legacy runs (missing workflowSource) as an explicit upgrade task."],"tags":["workflow","resume","backwards-compatibility","source-capture"],"backgroundTag":"legacy-run-source-missing","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}