Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Thank you for your interest in contributing to StellarStream! This guide will help you get started with our development process.

Check out the [FAQ.md](FAQ.md) for common contributor questions and troubleshooting tips.
Check out the [FAQ.md](FAQ.md) and [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) for common contributor questions and troubleshooting tips.

---

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ It includes:
* A backlog folder with implementation task drafts

This repository is intentionally lightweight and easy to extend.
For common questions and troubleshooting, see our `FAQ.md`.
For common questions and troubleshooting, see our `FAQ.md` and `docs/TROUBLESHOOTING.md`.
For real-world stream use cases and runnable API examples, see [`docs/USE_CASES.md`](docs/USE_CASES.md).
For production setup and operations, see `DEPLOYMENT.md` and `RUNBOOK.md`.
For security policy and reporting vulnerabilities, see `SECURITY.md`.
Expand Down
305 changes: 305 additions & 0 deletions docs/TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
# Troubleshooting Guide

Common issues encountered when developing or deploying StellarStream, organized by area.

---

## Table of Contents

1. [SOROBAN_DISABLED Mode Confusion](#1-soroban_disabled-mode-confusion)
2. [CONTRACT_ID Format Errors](#2-contract_id-format-errors)
3. [Indexer Not Starting](#3-indexer-not-starting)
4. [SQLite Lock Errors](#4-sqlite-lock-errors)
5. [Freighter Wallet Not Detected](#5-freighter-wallet-not-detected)

---

## 1. SOROBAN_DISABLED Mode Confusion

### 1.1 Backend exits on startup with Soroban config error

**Symptom:** Backend immediately exits, logging:

```
❌ Soroban configuration incomplete. Either provide both CONTRACT_ID and SERVER_PRIVATE_KEY, or set SOROBAN_DISABLED=true for local development.
```

**Cause:** Neither `CONTRACT_ID`/`SERVER_PRIVATE_KEY` nor `SOROBAN_DISABLED=true` is set. The default assumes Soroban is enabled and requires both variables.

**Fix:** For local development without on-chain operations, add to `backend/.env`:

```bash
echo 'SOROBAN_DISABLED=true' >> backend/.env
```

For production, set `CONTRACT_ID` and `SERVER_PRIVATE_KEY`.

---

### 1.2 Warning about SERVER_PRIVATE_KEY with SOROBAN_DISABLED

**Symptom:** Backend logs:

```
⚠️ SOROBAN_DISABLED=true is set and SERVER_PRIVATE_KEY is configured. The private key will not be used or logged in disabled mode.
```

**Cause:** Both `SOROBAN_DISABLED=true` and `SERVER_PRIVATE_KEY` are set simultaneously. The private key is ignored in disabled mode.

**Fix:** This is harmless. To silence the warning, remove `SERVER_PRIVATE_KEY` from `backend/.env` when running in disabled mode:

```bash
# Remove the SERVER_PRIVATE_KEY line from backend/.env
```

---

### 1.3 Indexer never starts in local dev mode

**Symptom:** Backend starts but indexer never runs. Logs show:

```
CONTRACT_ID not set, event indexer will not start
```

**Cause:** `SOROBAN_DISABLED=true` prevents the indexer from starting. This is intentional — local development mode skips Soroban polling.

**Fix:** This is expected behavior when `SOROBAN_DISABLED=true`. Streams created via the API will still work locally, but on-chain events (e.g., claims submitted via Freighter on testnet) will not be indexed. To re-enable, remove `SOROBAN_DISABLED` and configure `CONTRACT_ID`, `SERVER_PRIVATE_KEY`, and `RPC_URL`.

---

## 2. CONTRACT_ID Format Errors

### 2.1 CONTRACT_ID wrong length

**Symptom:** Backend exits with:

```
CONTRACT_ID validation failed
CONTRACT_ID validation issue: must be exactly 56 characters
Comment on lines +78 to +79

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Match the documented validation errors to the actual messages.

The supplied tests in backend/src/config/validateEnv.test.ts (Lines 23-71) assert messages containing STELLAR_CONTRACT_ID validation failed, while this guide shows CONTRACT_ID validation failed. Users searching the logs will miss the documented fix path; update both examples to the exact emitted messages or explicitly document the alias.

Also applies to: 111-112

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/TROUBLESHOOTING.md` around lines 78 - 79, Update both CONTRACT_ID
validation error examples in TROUBLESHOOTING.md to use the exact emitted
STELLAR_CONTRACT_ID messages asserted by validateEnv.test.ts, including the
character-length message, or explicitly document CONTRACT_ID as an alias while
preserving the exact log text.

```

**Cause:** The value set for `CONTRACT_ID` is not exactly 56 characters long.

**Fix:** Verify the length and fetch the correct ID:

```bash
# Check current length
echo ${#CONTRACT_ID}

# Retrieve the deployed contract ID
cat contracts/contract_id.txt

# Or re-deploy and capture the ID
cd contracts && make build
soroban contract deploy --wasm target/wasm32-unknown-unknown/release/stellar_stream.wasm --network testnet
```

Set the correct 56-character value in `backend/.env`:

```ini
CONTRACT_ID=C...
```

---

### 2.2 CONTRACT_ID uses G-prefixed account instead of C-prefixed contract

**Symptom:** Backend exits with:

```
CONTRACT_ID validation failed
CONTRACT_ID validation issue: must start with C (contract)
```

**Cause:** A Stellar account public key (starts with `G`) was used instead of a deployed contract ID (starts with `C`).

**Fix:** Deploy the contract to get a `C`-prefixed ID:

```bash
cd contracts && make build
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/stellar_stream.wasm \
--network testnet
```

Save the returned `C...` value as `CONTRACT_ID` in `backend/.env`.

---

### 2.3 Frontend claims fail with missing VITE_CONTRACT_ID

**Symptom:** Claiming a stream via the frontend fails. Browser console shows:

```
Missing VITE_CONTRACT_ID; cannot submit Soroban claim.
```

**Cause:** `VITE_CONTRACT_ID` is not set in `frontend/.env`. The frontend cannot submit on-chain claim transactions without it.

**Fix:** Set `VITE_CONTRACT_ID` to the same value as `CONTRACT_ID` in `frontend/.env`:

```bash
echo "VITE_CONTRACT_ID=<same value as backend CONTRACT_ID>" >> frontend/.env
```
Comment on lines +142 to +144

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the frontend environment command executable as written.

Copying this command verbatim appends the literal value <same value as backend CONTRACT_ID> to frontend/.env, which is not a valid contract ID. Use a shell expression that reads the backend value, or clearly mark the placeholder as something the developer must replace.

Proposed fix
-echo "VITE_CONTRACT_ID=<same value as backend CONTRACT_ID>" >> frontend/.env
+echo "VITE_CONTRACT_ID=$(grep '^CONTRACT_ID=' backend/.env | cut -d= -f2-)" >> frontend/.env
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```bash
echo "VITE_CONTRACT_ID=<same value as backend CONTRACT_ID>" >> frontend/.env
```
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/TROUBLESHOOTING.md` around lines 142 - 144, Update the frontend
environment setup command in the troubleshooting documentation so it does not
append the literal placeholder as the contract ID. Use a shell expression that
reads the backend CONTRACT_ID value, or clearly require the developer to replace
the placeholder before execution.


Then restart the frontend dev server.

---

## 3. Indexer Not Starting

### 3.1 "CONTRACT_ID not set" warning

**Symptom:** Backend logs:

```
CONTRACT_ID not set, event indexer will not start
```

**Cause:** Either `SOROBAN_DISABLED=true` (see [1.3](#13-indexer-never-starts-in-local-dev-mode)) or `CONTRACT_ID` is missing from the environment.

**Fix:** Check which case applies:

```bash
grep SOROBAN_DISABLED backend/.env
grep CONTRACT_ID backend/.env
```

If `SOROBAN_DISABLED=true` is present, this warning is expected. Otherwise, set `CONTRACT_ID` (see [section 2](#2-contract_id-format-errors)).

---

### 3.2 Circuit breaker open — RPC unreachable

**Symptom:** Logs show repeated:

```
[Circuit Breaker] State Transition: CLOSED -> OPEN
```

Followed by the indexer skipping polls.

**Cause:** The indexer failed 5 consecutive requests to the Stellar RPC node. Common reasons: incorrect `RPC_URL`, network outage, or rate limiting.

**Fix:**

```bash
# Verify RPC URL is correct
grep RPC_URL backend/.env

# Test connectivity
curl -s -o /dev/null -w "%{http_code}" https://soroban-testnet.stellar.org

# Check circuit breaker status via the API
curl http://localhost:3001/api/health
```

The circuit breaker automatically transitions to `HALF_OPEN` after 60 seconds (configurable via `CIRCUIT_BREAKER_TIMEOUT_MS`). If the RPC is healthy, it will recover automatically.

---

### 3.3 Invalid INDEXER_START_LEDGER

**Symptom:** Backend logs:

```
invalid INDEXER_START_LEDGER value
```

**Cause:** `INDEXER_START_LEDGER` environment variable is set to a non-numeric value.

**Fix:** Set a valid ledger sequence number or remove the variable:

```bash
# Remove the invalid value
unset INDEXER_START_LEDGER

# Or set a valid ledger sequence
echo "INDEXER_START_LEDGER=12345678" >> backend/.env
```

---

## 4. SQLite Lock Errors

### 4.1 Database locked in production

**Symptom:** Backend throws `SQLITE_BUSY` errors or requests hang.

**Cause:** Multiple backend processes are writing to the same SQLite database file. SQLite has limited concurrency.

**Fix:**

```bash
# Check for multiple backend processes
Get-Process -Name node -ErrorAction SilentlyContinue | Select-Object Id, StartTime

# Ensure only one instance is running
# Kill stale processes if needed
```
Comment on lines +234 to +240

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use an Ubuntu-compatible process check.

The PR objective calls out clean Ubuntu 22.04, but Get-Process is a PowerShell/Windows command and is unavailable in a default Ubuntu shell. Provide a POSIX equivalent or label this block as PowerShell and add a Linux command.

Proposed fix
-Get-Process -Name node -ErrorAction SilentlyContinue | Select-Object Id, StartTime
+pgrep -af node
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```bash
# Check for multiple backend processes
Get-Process -Name node -ErrorAction SilentlyContinue | Select-Object Id, StartTime
# Ensure only one instance is running
# Kill stale processes if needed
```
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/TROUBLESHOOTING.md` around lines 234 - 240, Update the process-check
block in TROUBLESHOOTING.md to use an Ubuntu/POSIX-compatible command for
listing node processes, or explicitly label the existing Get-Process example as
PowerShell and add a separate Linux command. Ensure the instructions still cover
identifying multiple backend instances and stale processes.


SQLite WAL mode and `busy_timeout=5000` are already enabled in `db.ts`, which mitigates most contention. The definitive fix is ensuring only one backend instance writes to the database.

---

### 4.2 Test database locked

**Symptom:** Backend tests fail with database locked errors.

**Cause:** A prior test run was interrupted, leaving the test database in a locked state.

**Fix:** Delete the test database and re-run:

```bash
rm -f backend/data/test-streams.db
cd backend && npm test
```

The database and schema are recreated automatically on next run.

---

## 5. Freighter Wallet Not Detected

### 5.1 Wallet button shows "Install Freighter" despite extension installed

**Symptom:** The wallet button in the UI displays "Install Freighter" even though the Freighter extension is installed.

**Cause:** Freighter may not be injected into the page (incognito mode, disabled extension, or page loaded before extension activated).

**Fix:**

1. Refresh the page fully (Ctrl+Shift+R).
2. Check that Freighter is enabled in browser extensions (chrome://extensions or about:addons).
3. Ensure the extension has permission to access `localhost`.
4. Reinstall from [freighter.app](https://freighter.app) if the issue persists.

---

### 5.2 Freighter installed but connection never completes

**Symptom:** Freighter is installed, but clicking "Connect Wallet" either does nothing or stays in "Connecting..." state.

**Cause:** Freighter is configured for **Public Network** instead of **Test Net**. The app expects testnet, and the SEP-10 challenge signatures fail.

**Fix:**

1. Click the Freighter extension icon in the browser toolbar.
2. Open **Settings** (gear icon).
3. Under **Network**, select **Test Net**.
4. Retry connecting.

---

### 5.3 "Connection cancelled" error

**Symptom:** Clicking "Connect Wallet" shows:

```
Connection cancelled — please approve the request in Freighter.
```

**Cause:** The Freighter popup was dismissed or declined without signing the approval.

**Fix:** Click "Connect Wallet" again and make sure to approve the request in the Freighter popup when it appears. The popup may be hidden behind the browser window.