{"record":{"id":"bc98775befb5e3b0","repo":"BoundaryML/baml","slug":"profiling-store-contains-a-symlink","errorCode":null,"errorMessage":"profiling store contains a symlink","messagePattern":"profiling store contains a symlink","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bex_prof_store/src/prof/backend/store.rs","lineNumber":1619,"sourceCode":"        .truncate(false)\n        .open(path)\n}\n\nfn write_synced_file(path: &Path, bytes: &[u8], platform: &dyn StorePlatform) -> io::Result<()> {\n    let mut file = OpenOptions::new().write(true).create_new(true).open(path)?;\n    file.write_all(bytes)?;\n    file.flush()?;\n    platform.sync_file(&file)\n}\n\nfn scan_physical_usage(root: &Path) -> io::Result<u64> {\n    fn scan(directory: &Path, root: &Path, total: &mut u64) -> io::Result<()> {\n        for entry in fs::read_dir(directory)? {\n            let entry = entry?;\n            let path = entry.path();\n            let file_type = entry.file_type()?;\n            if file_type.is_symlink() {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    \"profiling store contains a symlink\",\n                ));\n            }\n            if file_type.is_dir() {\n                scan(&path, root, total)?;\n            } else if file_type.is_file() {\n                let relative = path.strip_prefix(root).map_err(io::Error::other)?;\n                if relative == Path::new(\"publish.lock\")\n                    || relative == Path::new(\"usage.state\")\n                    || relative == Path::new(\"tmp/usage-state.pending\")\n                {\n                    continue;\n                }\n                *total = total\n                    .checked_add(entry.metadata()?.len())\n                    .ok_or_else(|| io::Error::other(\"profiling usage overflow\"))?;\n            } else {","sourceCodeStart":1601,"sourceCodeEnd":1637,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bex_prof_store/src/prof/backend/store.rs#L1601-L1637","documentation":"During a store integrity/usage scan, the recursive `scan` walker inspects each entry's file_type and rejects any symlink outright with InvalidData 'profiling store contains a symlink'. The store treats symlinks as a security and integrity hazard (they could redirect reads/writes outside the store root), so a symlink anywhere under the root fails the scan.","triggerScenarios":"Running the store scan/size-accounting routine when any entry under the profiling store directory (at any depth) is a symbolic link, as reported by entry.file_type().is_symlink().","commonSituations":"A user replaced a segment or shard file with a symlink to save space or point at another location; build/backup tooling created symlinks inside the data directory; syncing tools (e.g. dropbox, git) materialized symlinks in the store path.","solutions":["Find and remove the symlink: `find <store-root> -type l` then delete it and, if needed, copy the real target into place with `cp -L`.","Restore the directory entry as a regular file (replace the symlink with a copy of its target).","Reconfigure any sync/backup tooling to not create symlinks inside the profiling store directory.","Point the profiling store at a dedicated directory (e.g. under your app's data dir) not managed by symlink-producing tooling."],"exampleFix":"// shell\n// before: segment -> /elsewhere/segment.bin (symlink)\n// after\ncp -L /elsewhere/segment.bin segment.tmp && mv segment.tmp segment && find <store-root> -type l  # expect no output","handlingStrategy":"validation","validationCode":"fn store_has_symlinks(root: &Path) -> io::Result<bool> {\n    for entry in walkdir(root) {\n        if entry.file_type().is_symlink() { return Ok(true); }\n    }\n    Ok(false)\n}\n// run before opening the store; if true, clean the directory first","typeGuard":null,"tryCatchPattern":"match scan_store(&root) {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData && e.to_string().contains(\"symlink\") => {\n        replace_symlinks_with_copies(&root)?;\n        scan_store(&root)\n    }\n    other => other,\n}","preventionTips":["Never place symlinks inside the profiling store directory","Configure backup/sync tools (rsync without -a symlinks, dropbox, git) to not materialize symlinks there","Run `find <store-root> -type l` as a preflight check in deployment scripts"],"tags":["rust","io","filesystem","security","symlink"],"backgroundTag":"unsupported-operation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}