affaan-m/ECC · error · anyhow::Error
Legacy workspace not found
Error message
Legacy workspace not found: {} What it means
`build_legacy_migration_audit_report` canonicalizes the given legacy workspace path before scanning artifacts. `Path::canonicalize` fails when the path does not exist, and the `with_context` wrapper attaches this message including the displayed path. The audit cannot proceed without a valid source workspace.
Solutions
- Verify the legacy workspace path exists (`ls <path>`) and correct the argument or config value.
- Use an absolute path to avoid working-directory surprises.
- Restore or re-clone the legacy workspace if it was deleted, then rerun the audit.
Example fix
// before
build_legacy_migration_audit_report(Path::new("~/old-ws"))?;
// after
let src = expand_tilde("~/old-ws");
assert!(src.exists(), "legacy workspace missing: {}", src.display());
build_legacy_migration_audit_report(&src)?; Defensive patterns
Strategy: validation
Validate before calling
// Rust
let source = Path::new(raw_path);
if !source.exists() {
anyhow::bail!("legacy workspace does not exist: {}", source.display());
} Type guard
fn legacy_workspace_exists(p: &Path) -> bool {
p.exists()
} Try / catch
match build_legacy_migration_audit_report(&source) {
Err(e) if e.to_string().starts_with("Legacy workspace not found") => {
eprintln!("Check the path: {}", source.display());
}
other => other?,
} Prevention
- Store the legacy workspace path in config once, validated at startup.
- Use absolute paths and confirm mounts/drives exist before running migration tooling.
- Run `ls` on the path before long migration runs to fail fast.
When it happens
Trigger: Passing a nonexistent directory (or file path) to the legacy migration audit command; a typo'd path argument; a path removed between config-time and run-time.
Common situations: Running the migration audit on a machine where the old workspace lives at a different location; a renamed/moved legacy directory; passing a relative path from the wrong working directory; missing drive/mount on the machine running the audit.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Legacy workspace source must be a directory
- legacy scheduler jobs file must be a JSON object or array
- agent profile inheritance cycle
- all overlays must be readable local files
- all takes must be readable local files
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/ddca9c5d051724e1.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/main.rs:5132
if observation.pinned { "/pinned" } else { "" },
observation.entity_name
);
if let Some(session_id) = observation.session_id.as_deref() {
line.push_str(&format!(" | {}", short_session(session_id)));
}
lines.push(line);
lines.push(format!(" summary {}", observation.summary));
}
lines.join("\n")
}
fn build_legacy_migration_audit_report(source: &Path) -> Result<LegacyMigrationAuditReport> {
let source = source
.canonicalize()
.with_context(|| format!("Legacy workspace not found: {}", source.display()))?;
if !source.is_dir() {
anyhow::bail!(
"Legacy workspace source must be a directory: {}",
source.display()
);
}
let mut artifacts = Vec::new();
let scheduler_paths = collect_existing_relative_paths(
&source,
&["cron/scheduler.py", "jobs.py", "cron/jobs.json"],
);
if !scheduler_paths.is_empty() {
artifacts.push(LegacyMigrationArtifact {
category: "scheduler".to_string(),
readiness: LegacyMigrationReadiness::ReadyNow,
detected_items: scheduler_paths.len(),
source_paths: scheduler_paths,
mapping: vec![View on GitHub (pinned to 8321021c54)