Troubleshooting¶
ImportError — lionagi lazy imports¶
lionagi uses __getattr__-based lazy loading. Use public exports, not sub-package paths:
# ✓ Works — public export surface
from lionagi import Branch, iModel, Builder, HookRegistry
# ✗ Fails — sub-package __init__.py is empty
from lionagi.operations.communicate import communicate
# ✓ Works — full module path to the .py file
from lionagi.operations.communicate.communicate import communicate
from lionagi.operations.run.run import run_and_collect
Always import top-level names via import lionagi as li or from lionagi import <Name>.
RuntimeError — event loop in Jupyter¶
# ✗ Fails in Jupyter — already inside a running event loop
asyncio.run(branch.operate(...))
# ✓ Use await directly in Jupyter cells
result = await branch.operate(instruction="...")
Or install nest_asyncio before running:
import nest_asyncio
nest_asyncio.apply()
asyncio.run(branch.operate(...))
CLI: run-id not found¶
error: run not found: 20260420T103404-abc123
Run artifacts live under ~/.lionagi/runs/{run_id}/. Check what exists:
ls ~/.lionagi/runs/
li agent --resume <run-id>
CLI: --background output not visible¶
--background detaches the agent into a subprocess — output goes to the run directory, not to stdout. Read the artifacts directly:
cat ~/.lionagi/runs/<run-id>/run.json
cat ~/.lionagi/runs/<run-id>/stream/<branch-id>.buffer.jsonl
stream_persist JSONL behavior¶
When stream_persist=True, chunks write to {persist_dir}/{branch_id}.buffer.jsonl. Each line is {"content": "...chunk..."}.
Default persist_dir is ~/.lionagi/logs/runs when not set.
The return value of operate() / run() is the complete accumulated text (or parsed BaseModel), not the JSONL path.
Parse validation returns None or raw string¶
operate() defaults to handle_validation="return_value" — parse failures silently return the raw string. To diagnose:
- Check
handle_validation— set"raise"to surface the exact error. - Confirm
response_formatis a PydanticBaseModelsubclass (not a dataclass). - Enable fuzzy matching —
fuzzy_match=Truetolerates key name variations. - Lower
similarity_threshold— try0.75for noisy model output (default0.85).
result = await branch.operate(
instruction="Extract entity",
response_format=EntityModel,
handle_validation="raise", # surface the real error
)
Rate limit errors from provider¶
RateLimitError: 429 Too Many Requests
lionagi's rate limiter is proactive — configure it to queue before hitting the limit:
model = li.iModel(
model="gpt-4o",
limit_requests=60, # stay under provider RPM
limit_tokens=80_000, # stay under provider TPM
capacity_refresh_time=60,
)
AttributeError — branch property access¶
Branch properties like messages, tools, logs are read-only piles, not lists. Use pile access patterns:
# ✗ list operations don't apply
branch.messages[0] # index access on Pile uses UUID, not int position
# ✓ iterate or convert
for msg in branch.messages:
print(msg.content)
df = branch.to_df() # convert to DataFrame for tabular access
Next: Migration guide