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

  1. Pass a positive float (seconds) for parse_timeout, or omit it / pass None to disable
  2. Fix unit conversion so the value is in seconds and > 0 (e.g. ms/1000)
  3. Validate config-derived values before construction: if t is not None and t <= 0: t = None or a sane default
  4. 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

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.

Related errors


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)