can1357/oh-my-pi · error · anyhow::Error
Failed to load tree-sitter language: {err}
Error message
Failed to load tree-sitter language: {err} What it means
_validate_history_limit guards configuration values for history limits: None is allowed (meaning unset/default), but any non-None limit <= 0 is rejected with ValueError, since a zero or negative history cap is meaningless.
Source
Thrown at crates/pi-ast/src/parse_cache.rs:217
/// Semantics match a bare `Parser::new()` / `set_language` / `parse` sequence
/// exactly: `Err` when the grammar fails to load, `Ok(None)` when `parse`
/// yields nothing, `Ok(Some(tree))` otherwise. Trees carrying syntax errors are
/// cached like any other — `has_error()` is a property of the tree, so callers
/// that reject on it reach the identical verdict from a cached tree, and
/// repeated "does this parse" probes over the same broken file get the speedup
/// too.
pub fn parse_cached(code: &str, lang: SupportLang) -> Result<Option<Tree>> {
let key = key_for(code, lang);
// Bound the guard to a `let` so it drops at the end of this statement: an
// `if let` scrutinee would hold the lock across the early return.
let cached = lock().get(&key, code);
if let Some(tree) = cached {
return Ok(Some(tree));
}
let mut parser = Parser::new();
parser
.set_language(&lang.get_ts_language())
.map_err(|err| anyhow!("Failed to load tree-sitter language: {err}"))?;
let Some(tree) = parser.parse(code, None) else {
return Ok(None);
};
lock().insert(key, code, &tree);
Ok(Some(tree))
}
/// Occupancy and counters, for diagnostics.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ParseCacheStats {
pub entries: usize,
pub source_bytes: usize,
pub hits: u64,
pub misses: u64,
pub evictions: u64,
}
pub fn parse_cache_stats() -> ParseCacheStats {View on GitHub (pinned to 9690622007)
Solutions
- Pass None (or omit the option) to use the default/unlimited history, not 0.
- Fix env/config parsing: map sentinel values like 0 or -1 to None before constructing the client.
- Clamp computed limits: max(1, computed_limit).
- Catch ValueError around client construction to report a clear configuration error.
Example fix
// before
raw = os.environ.get("OMP_HISTORY_LIMIT", "0")
client = RpcClient(cmd, history_limit=int(raw)) # ValueError: must be > 0
// after
raw = os.environ.get("OMP_HISTORY_LIMIT")
history_limit = int(raw) if raw and int(raw) > 0 else None
client = RpcClient(cmd, history_limit=history_limit) Defensive patterns
Strategy: validation
Validate before calling
def clean_limit(v):
if v is None: return None
if not isinstance(v, int) or v <= 0:
raise ValueError(f"history limit must be a positive int or None, got {v!r}")
return v
history_limit = clean_limit(cfg.get("history_limit")) Type guard
def is_valid_limit(v: object) -> TypeGuard[Optional[int]]:
return v is None or (isinstance(v, int) and not isinstance(v, bool) and v > 0) Try / catch
try:
client = RpcClient(cmd, history_limit=limit)
except ValueError as exc:
if "must be greater than zero" in str(exc):
raise ValueError(f"bad history_limit config: {limit!r}") from exc
raise Prevention
- Use None (or omit) for unlimited/default — never 0 or -1.
- Sanitize env-derived config: map sentinel values to None before constructing the client.
- Validate config once at load time so zero/negative limits never reach client construction.
When it happens
Trigger: Passing history_limit=0 or a negative number to RpcClient configuration (constructor option, setter, or config file parsed into an int) — e.g. MAX_HISTORY=0 in environment-derived config.
Common situations: Env vars parsed with int() where the user set 0 or -1 to mean 'unlimited' (should be None/omitted instead), templated configs defaulting to 0, off-by-one sign errors computing a limit.
Understand the failure class
Background: "Invalid configuration value" and "Unsupported/Unknown setting value" errors: why libraries reject your config strings, numbers, and types — this error's family across 30 libraries.
Related errors
- Destination option ${key} must be a string
- Destination option ${key} must be a finite number
- Destination option ${key} must be a boolean
- ${destination} returned an invalid upload URL
- litterbox option ttl must be one of 1h, 12h, 24h, or 72h
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/aa17112b0a2fbacb.
Report an issue: GitHub.