xai-org/grok-build · error · std::io::Error
workflow source already registered: {run_id}
Error message
workflow source already registered: {run_id} What it means
WorkflowStore::register validates the run_id and then rejects registration if a source for that run_id is already present in its in-memory sources map, returning io::ErrorKind::AlreadyExists with the run_id. Each workflow run must have exactly one registered resume source (script/args/effort).
Source
Thrown at crates/codegen/xai-grok-shell/src/session/workflow/store.rs:133
state.token_leases.clear();
state.agent_usage_incomplete = true;
}
states.push(state);
}
}
(store, states)
}
pub(crate) fn register(
&self,
run_id: &str,
script: &str,
args: &serde_json::Value,
effort: Option<ReasoningEffort>,
) -> io::Result<()> {
validate_run_id(run_id)?;
if self.sources.lock().contains_key(run_id) {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!("workflow source already registered: {run_id}"),
));
}
if let Some(run_dir) = self.run_dir(run_id) {
let scripts_dir = run_dir.join("scripts");
std::fs::create_dir_all(&scripts_dir)?;
let args_json = serde_json::to_vec_pretty(args).map_err(io::Error::other)?;
atomic_write_new(&run_dir.join("args.json"), &args_json)?;
if let Some(effort) = effort {
atomic_write_new(&run_dir.join("effort"), effort.as_str().as_bytes())?;
}
atomic_write_new(&script_revision_path(&run_dir, 0), script.as_bytes())?;
atomic_write_replace(&run_dir.join("script.rhai"), script.as_bytes())?;
}
self.sources.lock().insert(View on GitHub (pinned to bc7f02eddd)
Solutions
- Check store has source / contains-key for the run_id first and skip re-registration
- Treat AlreadyExists as idempotent success if script and args match the existing registration
- Use a fresh run_id for genuinely new runs (e.g. UUIDv7 per run)
- If re-registration is legitimate, add an unregister/replace API instead of calling register again
Example fix
// before
store.register(&run_id, &script, &args, effort)?; // panics/fails on resume
// after
if store.source(&run_id).is_none() {
store.register(&run_id, &script, &args, effort)?;
} Defensive patterns
Strategy: validation
Validate before calling
if store.source(&run_id).is_some() {
// already registered: skip or verify script/args match
} else {
store.register(&run_id, &script, &args, effort)?;
} Type guard
fn is_registered(store: &WorkflowStore, run_id: &str) -> bool {
store.source(run_id).is_some()
} Try / catch
match store.register(&run_id, &script, &args, effort) {
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => { /* idempotent: verify and continue */ }
other => other?,
} Prevention
- Make registration idempotent: check before register, treat AlreadyExists as success when script/args match
- Issue a fresh run_id (UUIDv7) per run so duplicate ids never occur
- Guard retry logic so a retried register call short-circuits on AlreadyExists
- Register exactly once per run lifecycle, in one owner component
When it happens
Trigger: Calling register twice with the same run_id — e.g. re-registering on resume, a retried registration, or two components both registering the same run.
Common situations: Retry logic that re-invokes register after a transient failure that actually succeeded; resuming a run whose source was already registered in this process; duplicate event handling registering the same run_id twice.
Related errors
- workflow state has no registered resume source
- immutable workflow file already exists: {}
- Failed to set working directory to {:?}: {}
- Failed to load config: {e}
- reading command stdout: {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/d7373a45716e4223.
Report an issue: GitHub.