run-llama/liteparse · error · ValueError
parse_timeout must be > 0 seconds
Error message
parse_timeout must be > 0 seconds
What it means
WorkerPool accepts an optional parse_timeout that bounds each parse operation (triggering a hard kill of the worker). A timeout of zero or negative would kill every parse instantly, so __init__ rejects it with ValueError. Pass None to disable the timeout entirely.
Solutions
- Pass a positive float (seconds) for parse_timeout, or omit it / pass None to disable
- Fix unit conversion so the value is in seconds and > 0 (e.g. ms/1000)
- Validate config-derived values before construction: if t is not None and t <= 0: t = None or a sane default
- Guard with try/except ValueError at startup to fail fast with a clear config error
Example fix
# before
pool = WorkerPool(config, pool_size=4, parse_timeout=float(cfg.get('timeout_ms', 0)))
# after
timeout_s = float(cfg.get('timeout_ms', 30000)) / 1000.0
pool = WorkerPool(config, pool_size=4, parse_timeout=timeout_s if timeout_s > 0 else None) Defensive patterns
Strategy: validation
Validate before calling
if parse_timeout is not None and parse_timeout <= 0:
raise ValueError(f'parse_timeout must be > 0 seconds or None, got {parse_timeout}') Type guard
def is_valid_timeout(v: object) -> bool:
return v is None or (isinstance(v, (int, float)) and v > 0) Try / catch
try:
pool = WorkerPool(config, pool_size=4, parse_timeout=timeout)
except ValueError as e:
raise ConfigError(f'invalid liteparse timeout: {e}') from e Prevention
- Standardize timeout units as seconds everywhere; convert at the config boundary
- Treat 0 as 'unset' and map it to None before construction
- Document that None disables the timeout; don't use 0 for that
- Validate timeouts where config is loaded, not at pool construction time only
When it happens
Trigger: Constructing WorkerPool(config, pool_size, parse_timeout=0), a negative float, or a config value that parsed/converted to <= 0 (e.g. milliseconds-vs-seconds unit confusion, or 0 meaning 'no timeout' in the caller's mind).
Common situations: Unit conversion mistakes (seconds vs milliseconds) yielding tiny floats; passing 0 intending 'unlimited'; config files where the field exists but is 0 or negative; computing timeout from a user setting defaulting to 0.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- pool_size must be >= 1
- parse_timeout requires pool_size
- poolSize must be an integer >= 1
- parseTimeoutMs must be > 0
- parse of exceeded s; the worker process was killed
AI-assisted analysis of run-llama/liteparse@22d2dd8cd7 (2026-09-08).
Data as JSON: /api/errors/6c658c49db9d34de.
Report an issue: GitHub.
Appendix: source
Thrown at packages/python/liteparse/_pool.py:206
if stream:
stream.close()
except OSError:
pass
class WorkerPool:
"""Fixed-size pool of parse worker processes with a hard kill deadline."""
def __init__(
self,
config: Dict[str, Any],
pool_size: int,
parse_timeout: Optional[float] = None,
):
if pool_size < 1:
raise ValueError("pool_size must be >= 1")
if parse_timeout is not None and parse_timeout <= 0:
raise ValueError("parse_timeout must be > 0 seconds")
self._config = dict(config)
self._timeout = parse_timeout
self._idle: "queue.Queue[_Worker]" = queue.Queue()
self._lock = threading.Lock()
self._workers: List[_Worker] = []
self._closed = False
# Spawn eagerly: children import and construct their native parsers
# concurrently while the caller goes on with its own startup.
for _ in range(pool_size):
self._spawn_worker()
def _spawn_worker(self) -> None:
worker = _Worker(self._config)
with self._lock:
self._workers.append(worker)
self._idle.put(worker)
def _retire_worker(self, worker: _Worker) -> None:View on GitHub (pinned to 22d2dd8cd7)