{"record":{"id":"87454aa53f6dcb6a","repo":"xai-org/grok-build","slug":"workflow-state-has-no-registered-resume-source","errorCode":null,"errorMessage":"workflow state has no registered resume source","messagePattern":"workflow state has no registered resume source","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/session/workflow/store.rs","lineNumber":178,"sourceCode":"        Ok(())\n    }\n\n    fn manifest_for(&self, state: &WorkflowRunState) -> Option<WorkflowRunManifest> {\n        let revision = self\n            .sources\n            .lock()\n            .get(&state.run_id)\n            .map(|source| source.revision)?;\n        Some(WorkflowRunManifest {\n            version: WORKFLOW_RUN_MANIFEST_VERSION,\n            state: state.clone(),\n            script_revision: revision,\n        })\n    }\n\n    pub(crate) fn persist_now(&self, state: &WorkflowRunState) -> io::Result<()> {\n        let Some(manifest) = self.manifest_for(state) else {\n            return Err(io::Error::new(\n                io::ErrorKind::NotFound,\n                \"workflow state has no registered resume source\",\n            ));\n        };\n        let Some(run_dir) = self.run_dir(&state.run_id) else {\n            return Ok(());\n        };\n        let json = serde_json::to_vec_pretty(&manifest).map_err(io::Error::other)?;\n        atomic_write_replace(&run_dir.join(\"state.json\"), &json)\n    }\n\n    pub(crate) fn persist(&self, state: &WorkflowRunState) -> io::Result<()> {\n        let manifest = self.manifest_for(state).ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotFound,\n                \"workflow state has no registered resume source\",\n            )\n        })?;","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/session/workflow/store.rs#L160-L196","documentation":"persist_now writes workflow state synchronously but first requires a registered resume source via manifest_for; if the WorkflowRunState's run_id was never registered (or the store was reloaded without re-registration), it returns io::ErrorKind::NotFound \"workflow state has no registered resume source\". State cannot be persisted without knowing how to resume the run.","triggerScenarios":"Calling persist_now with a WorkflowRunState whose run_id has no entry in the store's sources map — e.g. after process restart/reload without re-registering, or persisting a state constructed for an unregistered run.","commonSituations":"Restoring state from disk after a crash but resuming before re-registering the script/args; a bug where register was skipped on a fast-fail path; persisting a stale state object from a previous session.","solutions":["Call register(run_id, script, args, effort) before persist_now","Ensure the resume/restore path re-registers sources before any persistence","Verify the run_id in the state matches the one registered (no id mismatch)","If persistence is optional for this run, skip persist_now instead of propagating the error"],"exampleFix":"// before\nstore.persist_now(&state)?; // NotFound after reload\n// after\nstore.register(&state.run_id, &script, &args, effort)?;\nstore.persist_now(&state)?;","handlingStrategy":"validation","validationCode":"if store.source(&state.run_id).is_none() {\n    store.register(&state.run_id, &script, &args, effort)?;\n}\nstore.persist_now(&state)?;","typeGuard":"fn can_persist(store: &WorkflowStore, state: &WorkflowRunState) -> bool {\n    store.source(&state.run_id).is_some()\n}","tryCatchPattern":"match store.persist_now(&state) {\n    Err(e) if e.kind() == io::ErrorKind::NotFound\n        && e.to_string().contains(\"resume source\") => {\n        store.register(&state.run_id, &script, &args, effort)?;\n        store.persist_now(&state)?;\n    }\n    other => other?,\n}","preventionTips":["Re-register all sources immediately after reloading/restarting the store","Keep one owner responsible for the register-before-persist ordering","Assert run_id consistency between registered sources and state objects","Add a debug check/log when persisting a state with no registered source"],"tags":["workflow","state-management","not-found","io"],"backgroundTag":"unregistered-resource-not-found","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}