> For the complete documentation index, see [llms.txt](https://docs.appmixer.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.appmixer.com/build-connectors-with-a-coding-agent/troubleshooting.md).

# When It Doesn't Work

Entered by symptom, not by chapter: find the line you saw on screen, or the sentence closest to what you are looking at. If you hit something that is not here, it belongs here.

## Setup and sign-in

### Every command fails, or the CLI cannot reach the instance

**Cause.** The CLI points at the Designer URL instead of the API host.

**Fix.** Take the *Appmixer API Base URL* from Backoffice, under **System → System Configuration**:

```bash
appmixer url <your API Base URL>
appmixer alias                      # confirm what is stored
```

### The agent doesn't mention the Appmixer skills at all

**Cause.** They are not installed, or an outdated copy is shadowing the released one.

**Fix.** Reinstall, then ask the agent to list what it has. Check the versions against `docs/compatibility.md` in the [appmixer-skills](https://github.com/Appmixer-ai/appmixer-skills) repository before debugging anything else — a mismatch looks like bugs everywhere.

## Building and testing components

### A list component returns nothing, and I cannot tell whether it is broken

**Cause.** The account is empty. An empty result looks the same whether the component works or not.

**Fix.** Test first against an endpoint that always returns one object, such as `/users/me/`. Then create a record in the service by hand and re-run the list.

### The component test passes, but the component ignores its inputs

**Cause.** The test only checks that a response came back. A `MakeApiCall` that drops every query parameter and header still passes. Two causes do it: the Designer's key-value input arrives as a JSON string the parser ignores, and Eventbrite ignores the query string of a GET carrying `Content-Type: application/json`.

**Fix.** Send a filter value that must fail. If it comes back `200`, your inputs are not reaching the API; compare with the same request through `curl`. See [Testing in Three Layers](/build-connectors-with-a-coding-agent/testing.md).

### A CSV full of real account data appeared inside my component's directory

**Cause.** A component with an `outputType: file` input writes a real file into its own folder when tested.

**Fix.** Delete it and add the pattern to `.gitignore` before you stage anything.

### Component tests are green but `connector verify` fails

**Cause.** They ask different questions: tests check that code runs, verify checks that the API's output matches the manifests.

**Fix.** Read the findings — they name the fields. See [Testing in Three Layers](/build-connectors-with-a-coding-agent/testing.md).

### `connector verify` reports `✗` for a field I know is optional

**Cause.** The schema verify read declares no `required`, so it cannot tell an optional field from a required one and treats every leaf as required. Three schemas do that: a static one without `required`, an out port declared through `options` alone, and a dynamic port built from an `outputType` input whose behaviour exports no `ITEM_SCHEMA`.

**Fix.** Declare `required` on the schema — honestly, so optional fields stay out of it — and export `ITEM_SCHEMA` from components with a dynamic out port. Optional fields then come back as `~`, which does not fail the run. If the field does not exist at all, remove it from the schema.

### `No stored credentials for "<connector>"`, on a connector that just authenticated fine

**Cause.** In CLI 2.6.0, `connector verify` reads only api-key style credentials; an OAuth login writes its token elsewhere in the same store. Fixed after 2.6.0 — on a newer CLI this does not happen.

**Fix.** Upgrade, or hand it the token:

```bash
(umask 077; echo '{"accessToken":"<token>"}' > /tmp/auth.json)
appmixer connector verify <connector> --auth /tmp/auth.json
rm /tmp/auth.json
```

### `Cannot find module '<your directory>/tmp/…'`, or a JSON syntax error, from `appmixer test component -i`

**Cause.** Two separate traps in how `-i` decides what it was given. An absolute path is resolved against the current directory anyway. And a path whose directory contains a dot — `.claude/in.json`, `appmixer.x/in.json` — is not recognised as a path at all, so it is parsed as JSON and fails on the first character.

**Fix.** Pass a path relative to the current directory, with no dots in the directory names, or give the JSON inline. Agents that keep scratch files under `.claude/` hit the second one.

### A dropdown cannot be tested from the CLI

**Cause.** Dropdown options come from a cached source call, and `appmixer test component` has no `staticCache`.

**Fix.** Check dropdowns in the Designer ([On the Instance](/build-connectors-with-a-coding-agent/on-the-instance.md#verify)) and let `appmixer e2e import` validate them.

### A trigger never fires

**Cause.** You are waiting for the source system to produce an event.

**Fix.** `appmixer test component <dir> --test` runs the component's `test()` method and returns a sample at once.

## Authentication

### The browser shows a bare 403 page instead of a consent screen

**Cause.** The provider rejects loopback redirect URIs. Its firewall page — often a plain CloudFront `403` — says nothing about Appmixer.

**Fix.** Use a hostname that resolves to your machine but is not loopback:

```bash
appmixer test auth login src/<vendor>/<connector>/auth.js \
  -u http://lvh.me:2300 -c <apiKey> -s <clientSecret>
```

`-u` and `TEST_SERVER_URL` do the same; `lvh.me` and `127-0-0-1.nip.io` both resolve to `127.0.0.1`. Register the rewritten URI as the CLI prints it. See [Your First Component](/build-connectors-with-a-coding-agent/first-component.md).

### The consent screen rejects the redirect URI

On Eventbrite: `Redirect URI hostnames must match`, whichever part differs.

**Cause.** The registered URI differs from the one sent. It is built from the **service** name only — `acme:eventbrite` gives `/auth/eventbrite/callback`, `appmixer:google:gmail` gives `/auth/google/callback`. Agents asked for it often add the vendor.

**Fix.** Copy the `redirect_uri` parameter from the authorization URL the CLI prints, and register exactly that.

### A red `Missing refresh token` line after a successful login

**Cause.** The service issues no refresh tokens — legal and common. Eventbrite's tokens do not expire.

**Fix.** None needed.

### I pasted a credential and authentication fails immediately

**Cause.** The wrong one of several values. Eventbrite issues four; on an OAuth connector the **API key** is the client id (`-c`) and the **client secret** is `-s`. The private and public tokens play no part.

**Fix.** Map the values before using any of them.

### OAuth works locally but the instance cannot start a flow

**Cause.** The instance has no copy of your app's client credentials.

**Fix.** An administrator runs `appmixer service-config set <vendor>:<connector>`; anyone else runs `appmixer user-service-config set <vendor>:<connector> <config-name>` and picks that config when connecting. See [On the Instance](/build-connectors-with-a-coding-agent/on-the-instance.md#give-the-instance-your-oauth-app).

### `Insufficient scope (status 403)` from `appmixer service-config`

**Cause.** Instance-wide service configuration needs an administrator.

**Fix.** Use a per-user custom OAuth config — `appmixer user-service-config set <vendor>:<connector> <config-name>` — or ask an administrator.

### `Missing vendor or service. (status 400)` from `appmixer auth url`

**Cause.** The colon form, `acme:eventbrite`, which the command's help suggests.

**Fix.** Use the dotted form: `appmixer auth url acme.eventbrite <ticket>`.

### After changing a connector's auth type: accounts fail, or tests pass suspiciously

**Cause.** Existing accounts hold a credential the components no longer read. And a green run can be the old credential succeeding, if it is still stored and the service returns the same string for both.

**Fix.** Re-authorize accounts rather than deleting them, and remove the old credential before re-running. See [Day-to-Day Work](/build-connectors-with-a-coding-agent/daily.md#changing-the-auth-type-of-a-published-connector).

## Publishing

### `no vendor assigned. (status 500)` on publish

**Cause.** Your account has no `vendor` property. The 500 is a permission refusal.

**Fix.** An administrator sets `vendor` in Backoffice, on the Users page. `appmixer user me` shows what you have.

### `Vendor mismatch in component.json` on publish

**Cause.** Your account's vendor is not the one in your manifests — usually a connector still named under `appmixer`.

**Fix.** Rename the connector, or have an administrator add the vendor to your list. Renaming is cheap before the first publish ([Scope and Research](/build-connectors-with-a-coding-agent/research.md)).

### Publishing works for me and fails for a colleague

**Cause.** You are an administrator; admin accounts skip the vendor check.

**Fix.** Compare `scope` and `vendor` in `appmixer user me` on both accounts.

### I published, but the instance still behaves like the old version

**Wrong user.** `appmixer alias <alias>` prints `Logged in as <email>`; the bare listing does not. In CLI 2.6.0, logging in again as somebody else does not change the session — it answers `Already logged in as <the old email>`. Run `appmixer logout` first.

**You are looking at the wrong thing.** `appmixer component ls` without `-m` prints names, not versions, and `appmixer component get` hands you every copy ever published, retired ones included. Ask the question that has an answer:

```bash
appmixer component ls -m <vendor>.<connector> --json
```

**A major version went out.** Flows resolve a patch or minor bump by themselves, but not a major one. A flow that requests the old major stops processing where that component sits, and a stopped flow refuses to start again until its pins are updated ([Shipping Changes](/build-connectors-with-a-coding-agent/shipping-changes.md#flows-follow-the-version)).

### The flow is running, the trigger fires, but one component never executes

**Cause.** Somebody published a **major** version of that component. Flows resolve a patch or minor bump by themselves, but not a major, and a flow that already holds the old one simply stops there — no error, no dead letter, the flow still reported as running.

**Fix.** Check what is served (`appmixer component ls -m <vendor>.<connector> --json`) against the version in the flow. Update the flow's version, import it again and restart it. Starting such a flow from stopped fails loudly instead, with a `400` ([Shipping Changes](/build-connectors-with-a-coding-agent/shipping-changes.md#flows-follow-the-version)).

### Some components show the old icon, or a generic one

**Cause.** Not established. After a republish, an instance can serve an old or generic icon for some components, varying between requests, while the stored component is correct.

**Fix.** Confirm the stored component with `appmixer component get`. If it is right, it is for the instance administrator.

## E2E flows

### `INVALID variable … (offered: $.<id>.out)`

**Cause.** Usually downstream of another failure: the Designer offers only `.out` when it could not generate the component's output options.

**Fix.** Look for an earlier error in the same output first.

### `account <id> failed its validity test (expired/revoked token?) — re-authenticate it`

**Cause.** `appmixer e2e import` preflights the bound account, and it no longer validates.

**Fix.** Re-authorize it and re-import. It keeps its id.

### `variable fetch error: … must have required property '<input>'` on import

**Cause.** A dropdown's source call is invalid — typically a dependent dropdown calling a list component without an input the list requires, or with a value it rejects. That dropdown can never load in the Designer.

**Fix.** Make the input optional in the called component's schema and assert it in the behaviour; pass only values it accepts. See [Scope and Research](/build-connectors-with-a-coding-agent/research.md#what-to-check-in-the-result).

### `appmixer e2e import` seems to hang

**Cause.** It is working: it creates flows, binds and checks accounts, and validates every variable, which takes minutes for several flows.

**Fix.** Give it a generous timeout. Killing it leaves flows partly imported.

### `appmixer e2e run` exits with code 2

**Cause.** Not a failure. `--fix` found nothing to repair deterministically and wrote a **fix brief** for your agent.

**Fix.** Hand the brief to the agent. It starts with `═══ NEEDS_FIX — fix brief for the calling agent ═══`; [Testing in Three Layers](/build-connectors-with-a-coding-agent/testing.md#the-loop) shows one.

### `Assertion failed: expected true to equal true`

**Cause.** A mistake in the test flow. Assert turns a boolean field into the string `"true"`, then compares it loosely with the expected value: JSON `true` coerces to `1` and `"true"` to `NaN`, so they never match. Numbers and numeric strings do match, which is why only booleans fail this way. The message prints its operands the wrong way round, hence the nonsense.

**Fix.** Write expected booleans as strings, then import and run again.

### `startFlow failed: commons.registerSignalReceiver is not a function`

**Cause.** One server of the instance failing inside the platform's own test components; `e2e run` exits `1`.

**Fix.** Run it again. If it persists, ask the instance administrator to restart the engine workers.

### `appmixer e2e results` returns `{}`

**Cause.** Not established; it can happen right after passing flows.

**Fix.** Rely on the `RESULT` line `appmixer e2e run` prints per flow.

### A `TokenError` in the middle of a run

**Cause.** The bound account's token stopped working during the run.

**Fix.** `--fix` rebinds and re-runs. If it recurs, re-authorize the account.

### The flow times out with zero errors logged

**Cause.** Possibly a provider outage, which looks exactly like a trigger that never fires.

**Fix.** Check the service is up — probe an endpoint you know works, or its status page — before you take the trigger apart.

## The agent

### The agent removed components from the instance without asking

**Cause.** Not improvisation: the `test-connector` skill prescribes remove-and-publish for a component whose definition looks stale, and nothing in the skills requires a stop before `appmixer remove`.

**Fix.** Updating never needs a remove — bump the changed components' versions and publish. To keep the decision yours, say so in the prompt or set the agent to ask before `appmixer remove` ([Shipping Changes](/build-connectors-with-a-coding-agent/shipping-changes.md#never-remove-to-update)).

### The agent created records in my account I did not approve

**Cause.** The test plan is the one point where the agent reliably asks before writing. Outside it, it may create records while exploring an API.

**Fix.** Tell the agent at the start that writes need your approval, and check the account afterwards.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.appmixer.com/build-connectors-with-a-coding-agent/troubleshooting.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
