> For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt.

# Troubleshoot factory runs

:::info

**Takeaways:**

- Start from the issue or pull request. `tessl launch list --link-type <its type> --link-value <its URL>` finds every run it started, including runs that failed early.
- No run linked means the event never reached a loop. Check delivery, the trigger's conditions, the loop, the environment, and credits, in that order.
- A run that `completed` didn't necessarily succeed. Read its outcome: it can also be `no_action` or `needs_input`.
- A passing connection check proves the configuration, not a run. Only a run linked to a real issue proves the factory works.

:::

You labeled an issue, or delegated it to Tessl, and nothing happened. Or a run started and you can't tell what it did. This page walks each stage between the event and the pull request, with the check that tells you whether that stage is the problem and what to do next. For the terms loop, action, trigger, and run, see the [Automations overview](/automations/overview.md).

## Find the run

Every run is linked to the issue or pull request whose event started it as soon as Tessl creates the run, so a run that failed before the agent started is still listed. List the runs for the item you're looking at:

```bash
# A GitHub issue
tessl launch list --link-type github_issue --link-value https://github.com/<owner>/<repo>/issues/<n> --limit 100 --json

# A pull request
tessl launch list --link-type github_pr --link-value https://github.com/<owner>/<repo>/pull/<n> --limit 100 --json

# A Linear issue
tessl launch list --link-type linear_issue --link-value <Linear issue URL> --limit 100 --json
```

Each run carries a `webUrl` that opens it in the browser. An empty list means no run started: go to [When no run started](#when-no-run-started). Otherwise, read the newest run with `tessl launch view <id>` and go to [When a run started](#when-a-run-started).

The runs that follow a pull request are linked to the pull request, not the issue. To get from an issue to its pull request, read the implementation run with `tessl launch view <id> --json`. The entry in `data.attributes.links[]` with `rel` set to `produced` is the pull request it opened. List that pull request's runs the same way.

## When no run started

Work through these in order and stop at the first one that explains it.

### The event is too recent

- **Check:** how long ago you labeled, delegated, or commented. A run starts about 90 seconds after the event, and events close together fold into one run.
- **Next step:** wait 2 minutes and list the runs again.

### No event reached Tessl

- **Check:** for a repo-defined loop, run `tessl doctor --automations` from the repository and read the **Event delivery** section. It covers only the triggers declared in the local `tessl.json`: for each one, it says whether that event, from this repository, reaches the workspace. A warning names the gap, such as the Tessl GitHub App not being installed on the repository, or an installation still waiting for the owner to accept it. When the file declares no triggers, the section doesn't appear, and that says nothing about delivery. For an app-defined loop, doctor doesn't check delivery: check the loop's triggers with `tessl schedule view <loop id>`, the GitHub App's access to the repository, and for Linear, **Check loop connection** in your organization's settings. Then look for the run itself, as [Find the run](#find-the-run) describes.
- **Next step:** fix the gap the warning or the configuration shows, then repeat the event. For Linear events, connect Linear to the organization and route the Linear team to the project, as [Event triggers](/automations/overview.md#event-triggers) describes.

### The event didn't match the trigger

- **Check:** compare the event with the trigger's `when` conditions. For a repo-defined loop, they're in `tessl.json`. For an app-defined loop, they're in `attributes.triggers` of `tessl schedule view <loop id> --json`. The usual mismatches are a different label name, a sender the trigger doesn't accept (some triggers accept only listed GitHub user IDs, or ignore bots), an issue or pull request that's closed, and a pull request on a branch the trigger doesn't follow.
- **Next step:** repeat the event so it matches, such as removing the label and adding the right one, or change the trigger's conditions.

### The loop is paused or missing

- **Check:** run `tessl schedule list --project-id <project id> --all --json`. Find the loop and read `attributes.status`. If no loop is listed for a trigger in `tessl.json`, read the **Loops** section of `tessl doctor --automations`: it says when the project hasn't processed a `tessl.json` yet, or has no event loop for the triggers the file declares.
- **Next step:** resume a paused loop with `tessl schedule resume <loop id>`. For a missing repo-defined loop, merge `tessl.json` to the default branch, because loops come from the copy on the default branch, not the one on disk. See [Stop, remove, and move loops](/automations/stop-and-change-loops.md).

### The environment isn't bound to the project

- **Check:** run `tessl schedule view <loop id>`. When a loop names an environment its runs can't use, the **Environment** line says why after the name, such as the project not being bound to it.
- **Next step:** an organization admin binds the project with `tessl environment bind <environment> --project <workspace>/<project>`. See [Bind projects to an environment](/schedules/environments.md#bind-projects-to-an-environment).

### The organization is out of credits

- **Check:** run `tessl org usage`. It reads "Out of credits. Actions are paused." when runs can't start.
- **Next step:** an organization admin adds credits. See [Tessl Platform Pricing](/tessl-platform-pricing.md).

If none of these explains it, collect the output of `tessl doctor --automations --json` and the event's time in UTC, and [give feedback](/support/giving-feedback.md) to the Tessl team.

## When a run started

`tessl launch view <id>` shows the run's **Status** and, once it has finished, its **Outcome**. The status combines what the platform recorded with what the agent reported, so read both before you decide what happened.

### Still pending

- **Check:** run `tessl launch view <id>` again a minute later. While a run works, **Updated** shows how recently it reported progress, about every 30 seconds. A run with no progress yet may be queued behind another run on the same issue or pull request.
- **Next step:** follow it live with `tessl launch logs <id> --watch`. To stop it, run `tessl launch cancel <id>`. Cancellation is asynchronous: the run reads `cancelled` once it stops.

### Error: preparation failed

`tessl launch view` shows **error** with an error code such as `RECIPE_FAILED`. That code alone doesn't say when the run failed: it also covers a run whose agent finished but wrote a result the run didn't accept. Read the preparation progress to tell them apart.

- **Check:** run `tessl launch progress <id> --filename prepare-subphases.json`. When `outcome` is `failed`, preparation failed before the agent started: nothing reached your repository, and `tessl launch logs` has no transcript to show. `first_failed` names the step that failed, such as `clone` (getting the repository), `cloud-launch-setup` (your repository's setup hook), `manifest-sync` (syncing its configuration), or `skill-install` (installing the skill). `tessl launch view <id>` shows the error code, and for workspace admins, the failure details below it.
- **Next step:** when `outcome` is `ok`, the preparation script passed, but that doesn't mean the agent ran: other setup tasks run after it and before the agent, such as registering MCP servers or starting Docker, and any of them can fail. Read the **Failed tasks** line and the failure details in `tessl launch view <id>`, and the transcript from `tessl launch logs <id>` if there is one. Go to [Agent failed](#agent-failed) only when they show the agent started. For `cloud-launch-setup`, fix the hook as [What happens when the hook fails](/automations/cloud-setup-hook.md#what-happens-when-the-hook-fails) describes. For any other step, check that the step's input exists: the repository and branch for `clone`, a `tessl.json` that `tessl doctor --automations` accepts for `manifest-sync`, and the skill's plugin for `skill-install`.

### Agent failed

The agent started and stopped without finishing. `tessl launch view` shows **agent failed** with the reason the agent reported. A run that shows **error** and says it finished without the skill reporting a result belongs here too.

- **Check:** read the reason, then the transcript: `tessl launch logs <id> > run.log`, and read the last messages and tool calls in the file. A run an event started has no way to wait for an answer, so when its agent needs one, it fails with the question as its reason.
- **Next step:** when the reason is a question, answer it as [Completed, waiting for your input](#completed-waiting-for-your-input) describes. Otherwise, fix what the transcript shows, such as a failing test command or a missing credential in the environment. Then repeat the event that started the run.

### Completed, waiting for your input

The run finished and its **Outcome** is `needs_input`: the agent asked a question only you can answer. A run an event started can't end this way: it reports its question as [Agent failed](#agent-failed). Either way, the question is a Tessl comment on the issue, and it says how to resume.

- **Check:** read the latest Tessl comment on the issue.
- **Next step:** answer it. On a Linear issue, answer in a comment and move the issue back to Todo. On a GitHub issue, reply on the issue, and your reply starts the next run. If no run starts a few minutes after you reply, remove the trigger label and add it again.

### Completed with nothing to do

The **Outcome** is `no_action`. The agent looked and found nothing to change, such as a pull request with no new feedback.

- **Check:** read the reason after the outcome in `tessl launch view <id>`, or the run's latest comment on the issue when it gives none.
- **Next step:** none if the reason is right. If it isn't, add what's missing to the issue and repeat the event.

### Completed and succeeded

The **Outcome** is `succeeded`: the agent finished its job. That job isn't always a pull request. An implementation run that found the issue blocked by another open issue also succeeds, after it comments on the issue to say so.

- **Check:** run `tessl launch view <id> --json` and read `data.attributes.links[]`. A link with `rel` set to `produced` is what the run made, such as the pull request it opened. A run with only `references` links made nothing new: read its latest comment on the issue.
- **Next step:** review the pull request. A pull request the factory opened is on a `tessl/` branch of your repository and carries the `tessl` label. The loop that answers reviews and fixes checks follows only those pull requests, so a pull request opened by hand, or from a fork, gets no follow-up runs.

### Canceled

- **Check:** look on the issue for a note saying the run was stopped. The usual cause is a person taking the issue back, which the follow ticket changes loop acts on, or someone running `tessl launch cancel`.
- **Next step:** to start again, repeat the event, or move a Linear issue back to Todo while it's still delegated to Tessl.

## Connection checks aren't runs

The factory has 2 checks that say it is set up. Neither proves that it runs.

- **`tessl doctor --automations`** validates the local `tessl.json`, the agent each action selects, the project's loops, and whether the events of each trigger the file declares reach the workspace. It doesn't check delivery for app-defined loops. It reads configuration and sends no event.
- **Check loop connection**, on the Linear integration in your organization's settings, checks the Linear connection and how each team is routed to a project and its loops. It reads configuration only: it sends no issue to a loop and starts no run, and it reports webhook delivery and loop runs as not verified. The Linear connection isn't offered on the EU region.

A factory works when a real event starts a run you can find with `tessl launch list --link-type <type> --link-value <URL>`. After setup, or after any change to triggers, environments, or the setup hook, label or delegate one small issue and follow it through this page.

## Related pages

- [Automations overview](/automations/overview.md)
- [Stop, remove, and move loops](/automations/stop-and-change-loops.md)
- [Cloud setup hook](/automations/cloud-setup-hook.md)
- [Environments](/schedules/environments.md)
- [CLI commands: Launch](/reference/cli-commands.md#launch)
