unclecode/crawl4ai · error · ValueError
Profile not found: {profile_path}
Error message
Profile not found: {profile_path} What it means
The module-level shrink_profile(profile_path, level, dry_run) helper validates that profile_path exists and is a directory before shrinking a Chrome profile. A missing path or a file (not dir) raises ValueError('Profile not found: ...'). Note it also understands Chrome's Default/ subdirectory layout and operates on that if present.
Source
Thrown at crawl4ai/browser_profiler.py:104
dry_run: bool = False
) -> Dict[str, Any]:
"""
Shrink a Chrome profile to reduce storage while preserving auth data.
Args:
profile_path: Path to profile directory
level: How aggressively to shrink (LIGHT/MEDIUM/AGGRESSIVE/MINIMAL)
dry_run: If True, only report what would be removed
Returns:
Dict with 'removed', 'kept', 'bytes_freed', 'size_before', 'size_after', 'errors'
"""
if level == ShrinkLevel.NONE:
return {"removed": [], "kept": [], "bytes_freed": 0, "errors": []}
profile = Path(profile_path)
if not profile.exists() or not profile.is_dir():
raise ValueError(f"Profile not found: {profile_path}")
# Chrome profiles may have data in Default/ subdirectory
target = profile / "Default" if (profile / "Default").is_dir() else profile
keep = KEEP_PATTERNS[level]
result = {"removed": [], "kept": [], "bytes_freed": 0, "errors": [], "size_before": _get_size(profile)}
for item in target.iterdir():
name = item.name
# Check if item matches any keep pattern
if any(name == p or name.startswith(p) for p in keep):
result["kept"].append(name)
else:
size = _get_size(item)
if not dry_run:
try:
shutil.rmtree(item) if item.is_dir() else item.unlink()
result["removed"].append(name)View on GitHub (pinned to 7e80152142)
Solutions
- Verify the path first: Path(p).is_dir() before calling.
- Pass the actual profile directory (the one containing Default/ or the profile files), absolute if possible.
- If you only have a profile name, use BrowserProfiler().shrink_profile(name) which joins profiles_dir for you.
Example fix
# before
shrink_profile('my-profile', ShrinkLevel.MEDIUM) # relative name -> not a dir
# after
profiler = BrowserProfiler()
result = profiler.shrink_profile('my-profile', ShrinkLevel.MEDIUM) # resolves under profiles_dir Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
p = Path(profile_path).expanduser().resolve()
if not p.is_dir():
raise ValueError(f'profile directory missing: {p}') Type guard
from pathlib import Path
def is_profile_dir(path) -> bool:
p = Path(path).expanduser()
return p.is_dir() Try / catch
try:
result = shrink_profile(path, level)
except ValueError as e:
if 'Profile not found' in str(e):
logger.warning('skipping missing profile %s', path)
result = None
else:
raise Prevention
- Prefer the BrowserProfiler method which resolves names under profiles_dir.
- Resolve paths to absolute before calling the free function.
- Existence-check before cleanup scripts iterate profiles.
When it happens
Trigger: Calling shrink_profile('/nonexistent/path'); passing a profile name instead of the resolved absolute path to the free function (the BrowserProfiler method resolves names — the free function does not); passing a .zip backup file path; profile was deleted after a previous shrink.
Common situations: Using the functional API directly instead of the class; relative paths resolved against an unexpected cwd; profiles_dir relocated between runs.
Related errors
- Profile not found: {profile_name_or_path}
- Local file not found: {local_file_path}
- Local file not found: {path}
- Container not found: ${config.container_selector}
- Timeout after {timeout}ms waiting for selector '{wait_for}'
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/bc10773e68e19cb5.
Report an issue: GitHub.