# Troubleshooting and Escalation

> A `remits-cli` skill reference. **Load this when** something behaved unexpectedly, or you have tried the same thing two or three times and it still misbehaves.
>
> The table of contents below carries **real line numbers** (`- L84  Some Heading`), resolved when
> this file is installed, so they are never stale. Read the head, pick your sections, and offset-read
> only those. The entry text is the heading verbatim, so it also greps.

## Table of Contents

- [Troubleshooting](#troubleshooting)
  - [When Something Doesn't Work as Expected](#when-something-doesnt-work-as-expected)
    - [Escalation Bundle (tooling/operational issue)](#escalation-bundle-toolingoperational-issue)

## Troubleshooting

| Symptom | Fix |
|---|---|
| 401 or `Not authenticated` | Run `remits-cli auth` |
| `account-info.json not found` | Run from the account repo root |
| Test not found (404) | New component not staged yet. Run `remits-cli components stage` first. For new tests (no ID), run by name not ID. |
| Stage shows 0 updated | No changes since last stage (hash dedup) |
| Test runs old code after edit | You forgot to stage, or you are looking at DB while a staged entry is still active. Run `remits-cli components status`; then `remits-cli components stage` to update staged code or `remits-cli components clear` to fall back to DB. |
| "Git credentials" or `git push` error | Git auth is required for commit (server pulls from git remote). Fix git authentication (SSH keys or HTTPS credentials) before retrying. Staging and testing still work without git. |
| Need to learn command behavior | Read the `remits-cli` skill and its references, repo docs, or CLI source. Do not run unsupported mutating subcommand variants such as `remits-cli components commit --help`; if a command unexpectedly mutates or commits, run `remits-cli doctor local-state` and inspect the active actor's repo-local session log before doing anything else. |
| Sync response reports unexpected deletes, creates, renames, uniqueness errors, or component ID drift | Stop immediately. Do not rerun sync, do not create replacement components to paper over the mismatch, and do not promote more changes. Preserve session logs/tool responses, compare `account-info.json`, local filenames, live inventory, and git history, then prepare a repair/escalation summary. |
| 500 / `Internal Server Error` from Remits | Stop normal task work. Capture the exact command, error, and response artifact, then escalate to a Remits system admin. Do not invent a workaround. |
| Tool parameters rejected | Tool schemas may be cached. Run `remits-cli tools` to refresh `.remits-cli/shared/tools/tools.json` with latest schemas. |
| Tool response missing | Run `remits-cli doctor local-state`, then check `./.remits-cli/actors/<local-agent>/tool-responses/` and any legacy flat `./.remits-cli/tool-responses/` fallback it reports. |
| Long-running tool times out | For `mcp_run_action`/`mcp_run_agent`, use the tool's own `executionMode:"async"` and poll with a `controlAction:"status"` call (see `command-reference.md` → *Tool Execution Lifecycle*). For other long tools without their own async, use `remits-cli tool --async true` and poll `remits-cli tool status --call-id <callId>`. `--timeout-ms` only adjusts the per-request HTTP timeout; it is not a substitute for async. |
| Need to continue tracking a long Action or Agent after terminal disconnect | Read `./.remits-cli/actors/<local-agent>/tool-responses/<callId>.json` for the returned `actionRunId`/`agentRunId`/`sessionId`/`threadGroupingId` (or the legacy flat fallback if `doctor local-state` reports it there). Re-poll the run with a `controlAction:"status"` call carrying that `actionRunId`/`agentRunId`, or inspect the agent session via `mcp_ai_session_search` with the `sessionId`. |
| Staged change has no effect in a live (non-CLI) run | Staged overrides resolve only under a CLI TestMode (`branchName`+`cliUserId`). Live webhooks and other non-CLI runtime paths still use the DB (trunk, or the account's subscribed variant). `commit` to make it durable. See `component-resolution.md`. |
| Need to know an account's shape (role, type, parents, namespace, branch, host/login routes) | Read `resolution` — from the repo's `account-info.json`, or `mcp_account_user_admin` `action:'account'` (cheap), or `mcp_account_view` (full inventory): `role`/`summary`, `type`, `resolvedDatabaseName`, `domainName`/`resolvedDomainName`, `authPath`/`targetPath`, `relationships`, `componentBranch`, plus top-level `componentBranches`. Never infer structure from the account's name. |
| Need the account tree below an account, or its users | In a local repo, read `account-hierarchy.json` for the generated tree. For live data, use `mcp_account_user_admin` (`action:'hierarchy'` with a `depth`, or `action:'users'`). `account-info.json` deliberately omits the tree. |
| Need to prove whether an account/user/record is test data | Check explicit flags: `resolution.testAccount` / hierarchy `testAccount`, `mcp_account_user_admin` `testAccount` / `testUser`, token inspect owner flags, and `mcp_record_listing` / `mcp_record_view` `testMode` for object/event/alert rows. Do not infer from names or branch labels. |
| Need account configuration values | In a local repo, read `account-configurations.json`. For live data, use `mcp_account_user_admin` (`action:'account'`) or `mcp_account_view`. `account-info.json` deliberately omits configurations. |
| An account has two parents and you don't know which one a run used | `resolution.relationships` lists every link with its own `branchName`/`databaseName`/`domainName`. A membership-only account with SEVERAL edges resolves **trunk and inherits nothing** until a path is named (`--as-account`, `--variant-branch`, or an edge host) — that is by design, not a bug. With exactly ONE membership edge it inherits normally, descendants included. |
| Documents missing / written to the wrong place | Compare `resolution.databaseName` (the account's own override) with `resolution.resolvedDatabaseName` (what is actually in effect), and check for a `databaseName` on one of the `relationships` edges. Data does not inherit; components do. |
| A custom hostname resolves to an unexpected account | Compare `resolution.domainName` with `resolvedDomainName` and the edge `domainName`s. An **edge** host wins over the account's own host and additionally supplies the path travelled (which is what makes that edge's branch variants apply). |
| Need users of an account, accounts of a user, or account-scoped user fields | Use `mcp_account_user_admin` (`action:'users'`, `action:'user'`, or `action:'user_update'`). Use `mcp_sql_query` on `user` / `user_account` only for raw join-table investigation. Remember user custom fields are stored **per bound account**, so the same person can differ per account. |
| One account behaves differently from its siblings on the same component | It probably subscribes to a **branch variant**. Check `remits-cli components branches` and `remits-cli components branch <name> --subscribers`, and reproduce with `remits-cli test run --as-account <ID>`. Do NOT "fix" this by adding per-account logic to the origin component. |
| Edits on a feature branch seem to run against trunk code | A branch with no committed variants and no subscribers resolves the account's **subscription** (trunk, if it subscribes to nothing) beneath what you staged — `components status` shows `FEATURE BRANCH … [subscription-fallback]` and names the world. To see a specific branch's overlays, run from that branch's checkout or pass `--variant-branch <name>`. |
| `components commit`/`sync` refused with `feature_branch_landing` | The branch is a feature branch, not a variant branch. Merge it into the branch the message names and land from that checkout. Do **not** pass `--create-variant-branch` to get past it — that flag deliberately creates a new variant branch nobody subscribes to. |
| A component vanished for one account after a variant-branch sync | Its file is missing from that branch, so the sync created a **tombstone** that hides it from subscribers. Restore the file on the branch and re-sync. Trunk is unaffected. |
| A variant Test suite fails wholesale, asserting trunk where you expect a variant | You are almost certainly running it from a **variant checkout**: `variantBranch` outranks every subscription, so the suite's own fixture accounts resolve YOUR branch. Re-run from trunk or with `--variant-branch none` before treating it as a regression. |
| `components sync` on a branch says "No changes detected" but trunk has moved | Re-run it; a trunk sync now invalidates the branch's cached verdict. If it still skips, the branch genuinely matches trunk - check `components branch <name>` for what is actually stored. |
| A sync summary reports `skipped: true` with `NO COMPONENTS WERE SYNCED` | The branch head matches the cached sync SHA, so the branch was never re-read — this is NOT an empty plan. It matters when something else changed the overlays at that same SHA: an ordinary re-sync then answers "nothing to do" forever. `--dry-run` always re-reads the branch and shows the real plan; `--force-tombstones` re-reads and applies it. |
| A branch sync stores overlays for components you never edited on the branch | **Trunk moved.** Sparseness compares the branch against CURRENT trunk, so editing a component on trunk without merging trunk into the branch turns it into a branch overlay on the next branch sync. The branch did not change. Merge trunk in, push, re-sync — the overlays prune. Check `components promotion` for the phase. |
| After promoting a `new_*` component to trunk, the branch still shows it as `added` | You have not re-synced the branch since the trunk sync. Merge trunk into the branch and `components sync`: the file adopts the promoted id and, if unchanged, removes its own overlay. If the branch carries BOTH `new_Foo.*` and `<id>_Foo.*`, the id file wins and the `new_` one is reported `skipped: superseded` - delete it. |
| After promoting a standalone Prompt, the branch still shows `OVERRIDDEN prompt:<id>` with only `purpose` changed | The trunk Prompt row does not match repo metadata. Ensure the Prompt sidecar has `description` and `purpose: CUSTOM`, run a platform build that imports Prompt `purpose`, re-sync trunk, merge back, and re-sync the branch. |
| A branch preview reports a `removed` component nobody deleted | Check whether that component has a file on **trunk**. A DB row with no trunk file is missing from every branch, so it reads as a removal everywhere (and the trunk sync tries to hard-delete it each run). Repair trunk, not the branch. |
| `--as-account <id>` resolves trunk, or 404s | The account probably has several edges each carrying a branch, so the anchor is ambiguous and the platform refuses to guess. Name the branch with `--variant-branch <name>`, and confirm the edge with `components branch <name> --subscribers`. |
| A branch variant is reported DRIFTED | The origin component changed after the variant was cut, so the branch is based on a stale version. `remits-cli components branch <name> --diff <id> --component-type <kind>` to compare, then reconcile the branch. |
| New source shown by `mcp_component_view` but old behavior persists after sync/commit | The compile cache (`CLOSURE_CACHE`) is keyed by `version:<N>:<sourceHash12>`, so a source change on the same version now invalidates it automatically — a run right after sync/commit picks up the new source. If old behavior still persists, confirm the run actually hit the synced instance and that no staged override is still shadowing DB (`remits-cli components status`). |
| Staged Reader test run throws `No enum constant ObjectType.<family>` | The staged entry has the component family in `type` (should be `kind`). Clear + re-stage; if it persists, inspect the staged payload with `mcp_cache` and escalate as a CLI/platform staging bug. |
| Unsure whether a run used staged vs DB source | Query `mcp_system_logs` for `Using Cached BCD` — `Signature: cli:<hash>` = staged, `version:<N>:<sourceHash12>` = DB. CLI/MCP tool results also report `componentSource` and `componentSignature` when available. |
| Service already running | Run `remits-cli status` to get the dashboard URL, or `remits-cli stop` before restarting. |
| Control center URL unknown | Read `~/.remits-cli/service-state.json` or run `remits-cli status` |
| Dashboard missing repos | Rebuild `~/.remits-cli/account-repos.json` with `remits-cli start` or the control center rescan action |
| Agent dispatch to wrong directory | Check `~/.remits-cli/account-repos.json` has the correct directory and that you resolved the account type correctly. A `CLIENT` ticket may still belong to a parent `PLATFORM` or `PRODUCT` repo for code changes. |

### When Something Doesn't Work as Expected

All `remits-cli` capabilities — staging, test execution, committing, tool calls — are known to work. The
most common cause is an operational mistake, above all forgetting to stage before running a test.

If you have followed the loop (**edit → stage → run**) and something still misbehaves after 2-3 attempts,
**stop trying workarounds** and decide which kind of problem it is:

- **A `remits-cli` / tooling operational issue** — staging, sync, dispatch, the listener, or the CLI itself
  misbehaving → use the **Escalation Bundle** below and ask the user to escalate to a Remits system admin.
- **A Remits back-stage platform defect or limitation** — the component *runtime* behaves wrong:
  Hibernate/session/optimistic-locking errors, detached-entity surprises, brittle lifecycle or tool
  behavior, a DSL method diverging from its guide → follow the **Back-Stage Escalation Workflow** in
  `features/front-stage-debugging-strategy.md` (`mcp_get_guide`), which owns it end to end: analyze the
  platform seam locally, open a PR on a feature branch (never merge it yourself), raise a
  `mcp_support_ticket`, and tell the user. **Do not normalize it into a front-stage workaround.**

The local clone of the core platform repo that workflow needs is tracked in
`~/.remits-cli/account-repos.json` under the reserved **`platform`** entry (default `~/remits`, override
with `REMITS_PLATFORM_DIR`); `remits-cli` clones it on first authenticated run if it is missing.

Apply the boy-scout rule to the guides themselves: **whenever you only solved the problem by reading the
core back stage because a front-stage guide was unclear or missing — even when there was no platform
defect at all — open a guide-only PR** updating the relevant guide in the platform repo's `docs/front-stage/`,
which is the source served to every account repo. Better guides over time are an explicit goal.

#### Escalation Bundle (tooling/operational issue)

1. **Create a single escalation bundle under `~/.remits-cli/issues/`.**
   Use a directory name like:
   - `~/.remits-cli/issues/<timestamp>-account-<accountId>-<short-slug>/`

   Populate that directory with enough information that the user or a Remits system admin can continue without re-running your work. Include at minimum:
   - `summary.md`
     - What you were trying to do
     - Why you were trying to do it
     - The expected behavior
     - The actual behavior
     - The exact commands you ran, in order
     - The key error messages or unexpected outputs
     - Whether the failure blocks staging, testing, sync, ticket routing, listener dispatch, or production investigation
   - `context.json`
     - `cwd`
     - target repo directory
     - `accountId`
     - account name
     - account `type`
     - branch name
     - current data mode
     - ticket ID if applicable
     - component names / IDs involved
   - Copies or references for the relevant supporting artifacts:
     - `remits-cli doctor local-state` output
     - `./.remits-cli/actors/<local-agent>/current-session.txt`
     - the active actor's repo session log from `./.remits-cli/actors/<local-agent>/sessions/`
     - any `./.remits-cli/actors/<local-agent>/tool-responses/<callId>.json` files involved
     - legacy flat `.remits-cli/` files only when `doctor local-state` says the relevant artifact is there
     - `~/.remits-cli/account-repos.json` if repo resolution may be relevant
     - `~/.remits-cli/activity.log` if service / websocket / agent-routing behavior may be relevant

2. **Use the global Remits CLI state to make the bundle self-contained.**
   - Run `remits-cli doctor local-state` to identify the active local actor and repo session log directory.
   - Record the exact repo directory and account context from `account-info.json`.
   - If repo selection or account targeting may be part of the issue, include the relevant entry from `~/.remits-cli/account-repos.json`.
   - If the problem involves support-ticket routing, agent registration, or websocket events, include the relevant lines from `~/.remits-cli/activity.log`.
   - If a tool call stored its full response externally, include that file path and summarize the important fields in `summary.md`.

3. **Stop and document the issue clearly for the user.**
   Tell the user where the escalation bundle lives and summarize:
   - what was attempted
   - what should have happened
   - what actually happened
   - why this appears to require a Remits system admin

4. **Ask the user to escalate to a Remits system admin.** The system admin has access to the Remits platform codebase and the `remits-cli` source code, and can diagnose and fix platform-level issues directly.

5. **Do not attempt creative workarounds** (renaming components, duplicating files, bypassing the CLI with raw API calls, etc.). If the platform has a real bug, workarounds mask the problem and make it harder to diagnose. It is better to have the issue fixed at the source than to build fragile workarounds around it.
