Skip to content
looot docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

troubleshooting skill

How the looot plugin's troubleshooting skill reads error codes and outcomes and decides what to do next.

troubleshooting loads automatically when a looot result carries needs_input, no_supply_for_job, no_runnable_provider, unknown_job, invalid_input, route_capped, route_no_fit, validation_error, insufficient_balance, idempotency_conflict, too_many_inflight_runs, forbidden, a 401, or outcome: "miss".

What it does

It reads status, error and outcome before anything else, since a tool call that worked can still hold a failed run. A tool error has code, message (with the fix in it), retryable and requestId. A failed run has error with code, message, whoseError (customer, provider or gateway), retryable and retryHint. For a job: refusal, the exact reason is in result.code, while error.code reads validation_error.

Code What it means What to do
needs_input No provider of the job accepts the input; result.needs lists each provider with the fields it needs. Add a named field, using the names from the search answer’s jobInputs, and use a new idempotencyKey.
no_supply_for_job No endpoint does this job. Search again in other words, or offer capability_request.
no_runnable_provider The job exists but nothing can run for this workspace right now. Retry later with a new idempotencyKey, or pick another job.
unknown_job The job: id doesn’t exist; the message suggests up to 3 close ids. Use a suggested id, or take capability from a search row.
invalid_input The email, url, domain or phone value is malformed. $0 charged. Fix the value and use a new idempotencyKey.
route_capped Every provider costs more than fallback.maxCostUsd; nobody was called. $0 charged. Raise maxCostUsd, after telling the user the price, or drop the cap.
route_no_fit Fallback had providers but none could take the input. $0 charged. Read route.skipped (needs_identity names the missing field) and add it.
validation_error An argument is wrong; the message names the field. Fix the named field; never guess argument names.
insufficient_balance Run status: "blocked", with topUp.checkoutUrl and a message. Show the link, wait for payment, retry with a new idempotencyKey.
idempotency_conflict This key was already used with a different input or endpoint. New run, new key.
too_many_inflight_runs Too many runs in flight for this workspace. Wait 2 seconds and retry with the same key.
forbidden The sign-in or token lacks runs.execute. Sign in again and allow running, or create a token with that scope.
401, tools missing Not signed in, or the sign-in expired. Use the setup skill.

Other signs it watches for: status: "completed" with outcome: "miss" (the provider answered but found nothing, and may still have charged; run the job with fallback so the next provider tries), outcome: "weak" (a flagged answer, such as a catch-all email or a verdict: "guessed" pattern guess, worth verifying before use), and status: "queued" or "running" after run (poll runs_get with the runId; never start a second run for it).

Worked example

Tool result: a run on job:people.email.find comes back {"status": "failed", "error": {"code": "validation_error"}, "result": {"code": "needs_input", "needs": [{"providerId": "hunter", "needs": ["company"]}]}}.

Agent’s answer: “That provider needed a company name as well as the domain. Let me add it and try again.” It reruns with company added and a new idempotencyKey.

See money for what’s charged when a run fails, and find-and-run for the full search-and-run loop.

Was this page helpful?