Skip to content

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:

  1. Check handle_validation — set "raise" to surface the exact error.
  2. Confirm response_format is a Pydantic BaseModel subclass (not a dataclass).
  3. Enable fuzzy matching — fuzzy_match=True tolerates key name variations.
  4. Lower similarity_threshold — try 0.75 for noisy model output (default 0.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