Hmbown/CodeWhale · error
legacy import refused: symlink or size bound
Error message
legacy import refused: symlink or size bound
What it means
native_memory import_legacy() imports a legacy markdown memory file only if it is a regular file of at most 1 MiB. Symlinks and oversized files are refused with this error — a security/robustness guard against symlink tricks (importing arbitrary files) and memory blowups from huge inputs.
Solutions
- Replace the symlink with a real copy of the target file inside the workspace.
- Split or trim the legacy file to under 1 MiB before importing.
- Import only the relevant portion of an oversized legacy file.
- Verify the path with `ls -l` (or fs::symlink_metadata) to confirm it is a plain file under the size bound.
Example fix
// before: symlinked legacy file ln -s ~/dotfiles/MEMORY.md ~/.codewhale/MEMORY.md // after: real file copy under 1 MiB cp ~/dotfiles/MEMORY.md ~/.codewhale/MEMORY.md && truncate -s 900K ~/.codewhale/MEMORY.md
Defensive patterns
Strategy: validation
Validate before calling
let meta = fs::symlink_metadata(path)?;
if meta.file_type().is_symlink() || meta.len() > 1024 * 1024 {
return Err("legacy import requires a plain file under 1 MiB".into());
} Prevention
- Store legacy memory files as real files, not symlinks into dotfile repos.
- Rotate/trim legacy markdown memory before it grows past 1 MiB.
- Check `ls -l` for symlink and size before pointing import_legacy at a path.
- Migrate to structured storage instead of repeatedly re-importing legacy files.
When it happens
Trigger: Calling import_legacy on a path that is a symlink (symlink_metadata reports a symlink file type) or a regular file larger than 1024*1024 bytes.
Common situations: Legacy MEMORY.md symlinked into a dotfiles repo; a legacy notes file that grew past 1 MiB over years of use; pointing import at a directory-like symlink or a synced/virtual file reported as oversized.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- audited skill path does not match owned package
- built-in plugin path may not be a symbolic link or reparse…
- bundle path escapes the config directory via a symlink…
- Codewhale-owned credential file
- Codewhale-owned xAI OAuth path must not be a reparse point
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8f235d1a60ff7861.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/native_memory.rs:506
};
let access = Access::operator(scopes)?;
let store = self.open_structured()?;
// Entry surfaces show only live memory; candidates and reviewed-off
// entries are visible in the Context Lens, not here.
store
.list(&access, None, limit)?
.iter()
.filter(|m| matches!(m.status, Status::Active | Status::Stale))
.map(|m| self.hit(&store, &access, m, &Snapshot::default()))
.collect()
}
pub fn import_legacy(&self, path: &Path) -> Result<bool> {
if !path.is_file() {
return Ok(false);
}
let meta = fs::symlink_metadata(path)?;
if meta.file_type().is_symlink() || meta.len() > 1024 * 1024 {
bail!("legacy import refused: symlink or size bound");
}
let text = fs::read_to_string(path)?;
let scope = Self::owner_scope();
let access = Access::operator(vec![scope.clone()])?;
let mut store = self.open_structured()?;
let report = codewhale_memory::import::markdown(
&mut store,
&access,
&scope,
"codewhale:legacy-memory",
&text,
)?;
if !report.rejected.is_empty() {
bail!(
"legacy import left {} rejected notes unchanged; inspect before retry",
report.rejected.len()
);
}View on GitHub (pinned to 73e0f67d83)