# Troubleshooting

> Symptom → cause → fix for the Shelve CLI and agent automation.

Quick fixes for the most common CLI issues. Run **shelve doctor** (or **shelve --json doctor**) first — it checks config, auth, API, cache, and agent context in one shot.

```bash [terminal]
shelve doctor
shelve --json doctor
```

## Error codes

<table>
<thead>
  <tr>
    <th>
      Code
    </th>
    
    <th>
      Meaning
    </th>
    
    <th>
      Fix
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        AGENT_BLOCKED
      </code>
    </td>
    
    <td>
      <code>
        pull
      </code>
      
       in an AI agent shell without <code>
        --yes
      </code>
    </td>
    
    <td>
      Use <code>
        shelve run -- <cmd>
      </code>
      
       or pass <code>
        --yes
      </code>
      
       if disk <code>
        .env
      </code>
      
       is required
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        AUTH_REQUIRED
      </code>
    </td>
    
    <td>
      No token
    </td>
    
    <td>
      <code>
        export SHELVE_TOKEN=…
      </code>
      
       or <code>
        shelve login
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CONFIG_MISSING
      </code>
    </td>
    
    <td>
      No <code>
        shelve.json
      </code>
      
       and missing env
    </td>
    
    <td>
      Create config or set <code>
        SHELVE_TEAM_SLUG
      </code>
      
       + <code>
        SHELVE_PROJECT
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        MISSING_ENV
      </code>
    </td>
    
    <td>
      No environment selected
    </td>
    
    <td>
      <code>
        --env staging
      </code>
      
       or <code>
        defaultEnv
      </code>
      
       in config
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        MISSING_INPUT
      </code>
    </td>
    
    <td>
      Non-interactive mode missing a flag
    </td>
    
    <td>
      Pass the flag shown in the error hint
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FETCH_FAILED
      </code>
    </td>
    
    <td>
      Network/API failure, no cache
    </td>
    
    <td>
      Go online once, or use <code>
        --offline
      </code>
      
       if cache exists
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        FORBIDDEN
      </code>
    </td>
    
    <td>
      Token lacks scope
    </td>
    
    <td>
      Create a token with read/write for the team/project
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        PROJECT_NOT_FOUND
      </code>
    </td>
    
    <td>
      Project missing
    </td>
    
    <td>
      Enable <code>
        autoCreateProject
      </code>
      
       or <code>
        shelve create
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        PUSH_BLOCKED
      </code>
    </td>
    
    <td>
      Push disabled for this env
    </td>
    
    <td>
      Check <code>
        sync.protectedEnvironments
      </code>
      
       or <code>
        allowPush
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        PULL_BLOCKED
      </code>
    </td>
    
    <td>
      Pull disabled for this env
    </td>
    
    <td>
      Set <code>
        sync.environments.<env>.allowPull
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        SYNC_CONFLICT
      </code>
    </td>
    
    <td>
      Diverging keys and <code>
        onPushConflict: fail
      </code>
    </td>
    
    <td>
      Run <code>
        shelve diff
      </code>
      
      , align values, or change policy
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ENV_PROTECTED
      </code>
    </td>
    
    <td>
      Server blocked write to protected env
    </td>
    
    <td>
      Update project sync policy in Shelve settings
    </td>
  </tr>
</tbody>
</table>

See also `shelve --help` for the full list of structured error codes.

## Exit codes

<table>
<thead>
  <tr>
    <th>
      Code
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Success
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      CLI or API error
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        128 + n
      </code>
    </td>
    
    <td>
      Child killed by signal (<code>
        run
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        129
      </code>
    </td>
    
    <td>
      Parent process gone / stdin EIO
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        130
      </code>
      
       / <code>
        143
      </code>
    </td>
    
    <td>
      SIGINT / SIGTERM (often treated as clean shutdown in <code>
        run
      </code>
      
      )
    </td>
  </tr>
</tbody>
</table>

## Common symptoms

### CLI hangs waiting for input

**Cause:** Interactive prompt (login, missing `--env`, confirmation).

**Fix:**

```bash [terminal]
export SHELVE_TOKEN=…
export SHELVE_TEAM_SLUG=…
export SHELVE_PROJECT=…
shelve --non-interactive doctor
```

### `shelve run dev` exits instantly

**Cause:** Script resolution failed or script exits immediately.

**Fix:**

```bash [terminal]
shelve run --debug dev
shelve run -- pnpm dev
```

### Secrets not updated after Shelve UI change

**Cause:** Old process env or stale cache.

**Fix:** Restart with `shelve run`, or use `--watch --restart-on-change`.

### `pull` fails in Cursor / Claude Code

**Cause:** Agent guard (`AGENT_BLOCKED`).

**Fix:** Prefer `shelve run -- <cmd>`. Only `shelve pull --yes` if you explicitly need a `.env` file.

### Offline / plane mode

**Fix:**

```bash [terminal]
# After one successful online run:
shelve run --offline -- pnpm build
```

### JSON automation parse errors

- Success → **stdout**: `{ "ok": true, "data": … }`
- Errors → **stderr**: `{ "ok": false, "error": { "code", "message" } }`
- `run` spawn metadata → **stderr** event: `{ "ok": true, "event": "child_spawned", … }`

Secret **values** are never included in JSON output.

## CI / GitHub Actions

Use the composite action:

```yaml
- uses: ./.github/actions/shelve-run
  with:
    token: ${{ secrets.SHELVE_TOKEN }}
    team-slug: my-team
    project: my-app
    env: ci
    command: pnpm test
```

Validate secrets before the main job:

```yaml
- run: npx @shelve/cli --json doctor
  env:
    SHELVE_TOKEN: ${{ secrets.SHELVE_TOKEN }}
    SHELVE_TEAM_SLUG: my-team
    SHELVE_PROJECT: my-app
```

## Agent skill

Install the published skills:

```bash [terminal]
npx skills add https://shelve.cloud
```

Catalog: `https://shelve.cloud/.well-known/skills/index.json` (skill: `shelve`).
