ArchiveBox/ArchiveBox · error · ValueError
Size value must resolve to a whole number of bytes.
Error message
Size value must resolve to a whole number of bytes.
What it means
parse_filesize_to_bytes accepts floats only if they represent a whole number of bytes; a fractional value like 1024.5 cannot be represented as an exact byte count, so it raises ValueError rather than silently truncating. This keeps size limits exact.
Source
Thrown at archivebox/misc/util.py:296
yield url
def parse_filesize_to_bytes(value: str | int | float | None) -> int:
"""
Parse a byte count from an integer or human-readable string like 45mb or 2 GB.
"""
if value is None:
return 0
if isinstance(value, bool):
raise ValueError("Size value must be an integer or size string.")
if isinstance(value, int):
return value
if isinstance(value, float):
if not value.is_integer():
raise ValueError("Size value must resolve to a whole number of bytes.")
return int(value)
raw_value = str(value).strip()
if not raw_value:
return 0
if raw_value.isdigit():
return int(raw_value)
match = re.fullmatch(r"(?i)(\d+(?:\.\d+)?)\s*([a-z]+)", raw_value)
if not match:
raise ValueError(f"Invalid size value: {value}")
amount_str, unit_str = match.groups()
multiplier = FILESIZE_UNITS.get(unit_str.lower())
if multiplier is None:
raise ValueError(f"Unknown size unit: {unit_str}")
View on GitHub (pinned to 74564b2822)
Solutions
- Round to an integer before passing: int(value) or round(value).
- Use a size string with a supported unit instead of raw float bytes (e.g. '1.5gb' is handled by the string branch).
- Fix the upstream computation to keep byte counts integral.
- Sanitize config values with math.floor/ceil at load time.
Example fix
// before half = total_bytes / 2 parse_filesize_to_bytes(half) // after half = total_bytes // 2 parse_filesize_to_bytes(half)
Defensive patterns
Strategy: type-guard
Validate before calling
def whole_bytes_ok(v) -> bool:
if isinstance(v, float):
return v.is_integer()
return isinstance(v, (int, str)) and not isinstance(v, bool) Type guard
def is_integral(v: object) -> bool:
return (isinstance(v, int) and not isinstance(v, bool)) or (isinstance(v, float) and v.is_integer()) Try / catch
try:
n = parse_filesize_to_bytes(value)
except ValueError:
n = int(float(value)) # only if truncation is acceptable Prevention
- Use integer math (//) for size computations
- Round before passing computed sizes
- Prefer unit strings ('1.5gb') over raw fractional floats
- Validate config values are whole numbers at load
When it happens
Trigger: Calling parse_filesize_to_bytes(1024.5) or a value computed by division (e.g. total/2.0) via clean_snapshot_max_size/clean_crawl_max_size or the add command.
Common situations: Computing sizes with division in a script then feeding the float to ArchiveBox config; JSON/YAML configs containing decimal sizes like 1.5mb entered as raw float 1572864.5; unit conversions done with float math.
Related errors
- Pass either records or stdin, not both
- Unknown argument(s): {', '.join(unknown)}
- Missing required parameter: name
- Unknown shell argument(s): {', '.join(unknown)}
- shell requires a non-empty code string
AI-assisted analysis of ArchiveBox/ArchiveBox@74564b2822 (2026-08-28).
Data as JSON: /api/errors/6a75c32cd2b9d3f5.
Report an issue: GitHub.