{"record":{"id":"803d731067232d43","repo":"shareAI-lab/learn-claude-code","slug":"resume-args-do-not-match-the-original-run","errorCode":null,"errorMessage":"resume args do not match the original run","messagePattern":"resume args do not match the original run","errorType":"validation","errorClass":"WorkflowInputError","httpStatus":null,"severity":"error","filePath":"s16_workflow_runtime/code.py","lineNumber":564,"sourceCode":"        if resuming:\n            run_id = validate_run_id(resume_from_run_id)\n        else:\n            run_id = reserve_run_id(meta)\n        with workflow_run_lock(run_id):\n            return await self._call_locked(\n                meta, script_fn, args, run_id, resuming\n            )\n\n    async def _call_locked(self, meta, script_fn, args, run_id, resuming):\n        if resuming:\n            snapshot = _read_snapshot(run_id)\n            if snapshot.get(\"workflowName\") != meta[\"name\"]:\n                raise WorkflowInputError(\"resume runId does not match workflow meta\")\n            saved_args = snapshot.get(\"args\", {})\n            if args is None:\n                args = saved_args\n            elif args != saved_args:\n                raise WorkflowInputError(\"resume args do not match the original run\")\n            journal = WorkflowJournal(run_id, resume=True)\n        else:\n            args = args or {}\n            journal = WorkflowJournal(run_id, resume=False)\n        task_id = create_task_id(run_id)\n\n        task = LocalWorkflowTask(task_id, run_id, meta)\n        # Record the launch envelope before workflow execution starts.\n        launched = {\"status\": \"async_launched\", \"taskId\": task_id,\n                    \"taskType\": \"local_workflow\", \"runId\": run_id,\n                    \"workflowName\": meta[\"name\"]}\n        task.event(\"async_launched\", runId=run_id, taskId=task_id)\n        task.event(\"task_started\", workflow=meta[\"name\"],\n                   phases=\",\".join(meta.get(\"phases\", [])) or \"-\",\n                   resume=resuming)\n        _write_json(STORE / f\"{run_id}.json\", {\n            \"runId\": run_id,\n            \"workflowName\": meta[\"name\"],","sourceCodeStart":546,"sourceCodeEnd":582,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/s16_workflow_runtime/code.py#L546-L582","documentation":"On resume, _call_locked() compares caller-supplied args against the args persisted in the run snapshot: passing args=None adopts the saved args, but passing explicit args that differ raises WorkflowInputError('resume args do not match the original run'). Journal cache keys are derived from prompts built from args, so changed args would make replay ambiguous.","triggerScenarios":"run_workflow(name, args={...}, resume_from_run_id=<id>) where the dict differs (even by one key or value) from snapshot['args'] recorded at launch.","commonSituations":"Tweaking the change description or options between the failed run and the resume attempt; defaults injected client-side that differ from what the original caller sent; key-order-independent dict comparison still failing on nested value changes.","solutions":["Omit args entirely on resume (args=None) to reuse the original run's arguments.","Pass byte-identical args to the original call, including nested values.","If you genuinely need different args, start a new run instead of resuming."],"exampleFix":"# before\nawait run_workflow(\"review\", args={\"changes\": diff_v2}, resume_from_run_id=rid)\n\n# after\nawait run_workflow(\"review\", resume_from_run_id=rid)  # reuses saved args","handlingStrategy":"validation","validationCode":"from s16_workflow_runtime import _read_snapshot\nsaved = _read_snapshot(run_id)[\"args\"]\nif args is not None and args != saved:\n    raise ValueError(\"pass args=None or the exact original args\")\nawait run_workflow(name, resume_from_run_id=run_id, args=args)","typeGuard":null,"tryCatchPattern":"try:\n    await run_workflow(name, args=args, resume_from_run_id=rid)\nexcept WorkflowInputError as e:\n    if \"args do not match\" in str(e):\n        return await run_workflow(name, resume_from_run_id=rid)  # reuse saved args\n    raise","preventionTips":["Default to args=None on resume; only pass args when you intend them to be identical.","Persist the exact args dict you launched with (it is in the snapshot) and replay it verbatim.","Treat 'resume with different inputs' as a new run by convention."],"tags":["workflow","resume","args","snapshot","validation"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}