affaan-m/ECC · error · ValueError
symlink output is not allowed
Error message
symlink output is not allowed: {path} What it means
validate_output in blender_prop.py rejects output paths that are, or sit under, a symlink, treating symlinks as a path-escape vector so writes cannot land outside the intended output directory.
Solutions
- Replace the symlink with a real directory
- Choose a different output path with no symlinks in its chain
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at skills/taste-application/scripts/blender_prop.py:108 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/c9f3f8aeb605ce57.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/blender_prop.py:108
peak = max(range(len(zones)), key=lambda i: (zones[i][0] ** 2 + zones[i][2] ** 2))
L = centres[peak] if peak < len(centres) else 50.0
# Push L up: this is a LIGHT, not a surface, so it needs to be emissive
# bright while keeping the measured hue direction.
return _lab_to_linear_srgb(min(95.0, L * 2.4), zones[peak][0], zones[peak][2])
def validate_settings(frames: int, width: int, height: int, fps: float) -> None:
for name, value, limit in (("frames", frames, 108000), ("width", width, 16384),
("height", height, 16384), ("fps", fps, 240)):
if (isinstance(value, bool) or not isinstance(value, (int, float))
or not math.isfinite(value) or not 1 <= value <= limit
or (name != "fps" and int(value) != value)):
raise ValueError(f"{name} must be finite, positive and within {limit}")
def validate_output(path: Path) -> None:
if any(part.is_symlink() for part in (path, *path.parents)):
raise ValueError(f"symlink output is not allowed: {path}")
if path.exists():
raise ValueError(f"refusing to overwrite existing output: {path}")
def validate_bounds(lower, upper) -> None:
dimensions = [upper[i] - lower[i] for i in range(3)]
if (not all(math.isfinite(v) for v in (*lower, *upper))
or any(v < 0 for v in dimensions) or not 1e-9 < max(dimensions) < 1e12):
raise ValueError("mesh has invalid or empty geometry bounds")
def camera_distance(radius: float, width: int, height: int) -> float:
"""Fit the original bounding sphere with the original 50 mm / 36 mm camera."""
horizontal_half = math.atan(36 / (2 * 50))
vertical_half = math.atan(math.tan(horizontal_half) * height / width)
return max(radius * math.hypot(3.2, 0.8),
radius / math.sin(min(horizontal_half, vertical_half)) * 1.05)
View on GitHub (pinned to 8321021c54)