# Troubleshooting

This guide covers common errors you may encounter when working with Sling API specifications and how to resolve them.

## Common Error Messages

### Endpoint Errors

| Error Message                          | Cause                                         | Solution                                                                        |
| -------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------- |
| `endpoint not found: X`                | The endpoint name doesn't exist in the spec   | Check spelling, run `sling conns discover CONN_NAME` to see available endpoints |
| `endpoint is disabled in spec`         | Endpoint has `disabled: true`                 | Remove the `disabled` field or set it to `false`                                |
| `duplicate endpoint name generated: X` | Dynamic endpoints created the same name twice | Ensure your dynamic endpoint name template produces unique names                |

### Queue Errors

| Error Message                            | Cause                                         | Solution                                                        |
| ---------------------------------------- | --------------------------------------------- | --------------------------------------------------------------- |
| `did not declare queue X in queues list` | Queue is used in a processor but not declared | Add the queue name to the top-level `queues:` list in your spec |

### Authentication Errors

| Error Message                                                              | Cause                                   | Solution                                                              |
| -------------------------------------------------------------------------- | --------------------------------------- | --------------------------------------------------------------------- |
| `could not authenticate`                                                   | Authentication configuration is invalid | Verify secrets, tokens, and credentials in your env.yaml              |
| `unsupported OAuth2 flow: X`                                               | Invalid OAuth2 flow type specified      | Use one of: `client_credentials`, `authorization_code`, `device_code` |
| `client_secret is required for client_credentials flow`                    | Missing OAuth2 client secret            | Add `client_secret` to your connection secrets                        |
| `authorization_url or derived URL is required for authorization_code flow` | Missing authorization URL               | Add `authorization_url` to your authentication config                 |
| `device_auth_url or derived URL is required for device_code flow`          | Missing device auth URL                 | Add `device_auth_url` to your authentication config                   |
| `failed to authenticate`                                                   | Authentication request failed           | Check API credentials, verify auth URLs, enable `--trace` for details |

### Response Processing Errors

| Error Message                                     | Cause                                      | Solution                                                                     |
| ------------------------------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------- |
| `need at least 2 lines to build records from csv` | CSV response is empty or only has a header | Ensure the API returns a header row plus at least one data row               |
| `could not evaluate jmespath`                     | Invalid JMESPath expression                | Test your expression with an online JMESPath tester; check for syntax errors |
| `error converting record to map`                  | Response data structure is unexpected      | Verify the JMESPath returns an array of objects, not primitive values        |

### Request & Iteration Errors

| Error Message                                   | Cause                                       | Solution                                                           |
| ----------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------ |
| `empty request url`                             | URL is not set or evaluated to empty        | Check `request.url` and ensure state variables are defined         |
| `loop expression is not an array or a queue`    | `iterate.over` doesn't evaluate to an array | Ensure the expression returns an array or references a valid queue |
| `invalid 'into' variable`                       | Wrong format for iteration variable         | Use format `state.variable_name` (e.g., `state.current_id`)        |
| `request loop into value must be state.<field>` | Iteration variable not in state namespace   | Prefix with `state.` (e.g., `state.item` not just `item`)          |

### Processor Errors

| Error Message                                              | Cause                                     | Solution                                                                      |
| ---------------------------------------------------------- | ----------------------------------------- | ----------------------------------------------------------------------------- |
| `empty response processor expression`                      | Processor has no `expression` field       | Add an `expression` to the processor                                          |
| `empty response processor output`                          | Processor has no `output` field           | Add an `output` destination (e.g., `record.field`, `state.var`)               |
| `invalid aggregation type`                                 | Unknown aggregation specified             | Use one of: `maximum`, `minimum`, `first`, `last`, `collect`                  |
| `cannot write aggregated value to queue`                   | Trying to aggregate into a queue          | Remove `aggregation` when writing to queues; queues receive individual values |
| `env. and context.store. outputs require aggregation type` | Missing aggregation for env/store outputs | Add an `aggregation` field (e.g., `aggregation: last`)                        |

### Rule & Retry Errors

| Error Message                       | Cause                     | Solution                                                                    |
| ----------------------------------- | ------------------------- | --------------------------------------------------------------------------- |
| `number of attempts exhausted: X/Y` | All retry attempts failed | Check API availability, increase `max_attempts`, or review backoff strategy |
| `rule met to fail: <condition>`     | A fail rule was triggered | Check response status code; verify authentication and request parameters    |

### License Errors

| Error Message                                                | Cause                            | Solution                                                      |
| ------------------------------------------------------------ | -------------------------------- | ------------------------------------------------------------- |
| `please use the official sling-cli release for reading APIs` | CLI Pro token missing or invalid | Get a CLI Pro token from [slingdata.io](https://slingdata.io) |

## Debugging Techniques

### Using Debug and Trace Flags

```bash
# Basic debugging - shows request flow and status codes
sling conns test MY_API --endpoints endpoint_name --debug

# Detailed tracing - shows full request/response details
sling conns test MY_API --endpoints endpoint_name --trace
```

**Debug output includes:**

* API requests being made
* Response status codes
* Record counts
* Pagination details
* State variable changes

**Trace output adds:**

* Full request headers and parameters
* Response headers
* JSON response bodies (truncated for large responses)
* Detailed expression evaluation
* Auth token refresh events

> **Warning:** The `--trace` flag may expose sensitive information like authorization tokens. Don't share unredacted logs.

### Testing Individual Endpoints

```bash
# List all available endpoints
sling conns discover MY_API

# Test a specific endpoint
sling conns test MY_API --endpoints users

# Test multiple endpoints
sling conns test MY_API --endpoints users,orders,products

# Test with pattern matching
sling conns test MY_API --endpoints "user_*"
```

### Limiting Data During Testing

Set an environment variable to limit records:

```bash
export SLING_TEST_ENDPOINT_LIMIT=10
sling conns test MY_API --endpoints large_endpoint
```

Or use the `limit` property in your endpoint:

```yaml
response:
  records:
    jmespath: "data[]"
    limit: 10  # Only process 10 records during testing
```

## Authentication Troubleshooting

### OAuth2 Issues

**Token not refreshing:**

* Verify `authentication_url` is correct
* Check that scopes are sufficient
* Tokens are stored in `~/.sling/api/tokens/{connection_name}.json` - delete to force re-auth

**Authorization code flow not working:**

* Ensure `redirect_uri` matches your OAuth app configuration
* Check `authorization_url` is correct
* Verify scopes include required permissions

**Device code flow timing out:**

* The user must complete authorization in the browser within the time limit
* Verify `device_auth_url` is correct

### Static/Bearer Token Issues

* Verify the token hasn't expired
* Check token format (some APIs require `Bearer` prefix, others don't)
* Ensure secrets are correctly referenced: `{secrets.api_key}`

## Pagination Troubleshooting

### Not fetching all pages

Check your `stop_condition`:

```yaml
pagination:
  stop_condition: "length(response.records) == 0"  # Stops when empty
  # OR
  stop_condition: 'jmespath(response.json, "has_more") == false'  # API-specific
```

Use trace to see pagination flow:

```bash
sling conns test MY_API --endpoints paginated_endpoint --trace
```

Look for:

* `stop_condition` evaluation results
* `next_state` changes between requests

### Cursor/offset not updating

Ensure `next_state` expressions reference the correct response fields:

```yaml
pagination:
  next_state:
    cursor: '{jmespath(response.json, "pagination.next_cursor")}'
    # OR
    offset: '{state.offset + state.limit}'
```

## JMESPath Troubleshooting

### Common JMESPath Issues

**Empty records array:**

* Verify the path to your data in the response JSON
* Test with `[*]` to get all top-level elements
* Use `--trace` to see the actual response structure

**Syntax errors:**

* Use an [online JMESPath tester](https://jmespath.org/) to validate expressions
* Remember: property names with special characters need quotes: `"content-type"`
* Arrays use `[]` suffix: `data.items[]`

**Examples:**

```yaml
# Top-level array
jmespath: "[*]"

# Nested array
jmespath: "data.results[]"

# Filter records
jmespath: "users[?status=='active']"

# Project specific fields
jmespath: "data[].{id: id, name: full_name}"
```

## Getting Help

If you're still having issues:

1. **Check the logs** with `--trace` for detailed error information
2. **Verify your spec** syntax by running `sling conns test`
3. **Test the API directly** with curl or Postman to rule out API issues
4. **Search existing issues** on [GitHub](https://github.com/slingdata-io/sling-cli/issues)
5. **Ask the community** on [Discord](https://discord.gg/q5xtaSNDvp)
6. **Contact support** at <support@slingdata.io>
