Skip to content
Back to skills

1097 Troubleshooting B915c796

ASecurity

Comprehensive guide to debugging Apex code, LSP validation, dependency management, and common deployment issues. ---

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
testingpythongojavabashtestingdebuggingcode-reviewapidatabasedocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1097-troubleshooting_b915c796 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1097 Troubleshooting B915c796?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1097 Troubleshooting B915c796
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1097-troubleshooting-b915c796/badge)](https://www.skillsdirectory.com/skills/tools-only-1097-troubleshooting-b915c796)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Apex Troubleshooting Guide

Comprehensive guide to debugging Apex code, LSP validation, dependency management, and common deployment issues.

---

## Table of Contents

1. [LSP-Based Validation (Auto-Fix Loop)](#lsp-based-validation-auto-fix-loop)
2. [Cross-Skill Dependency Checklist](#cross-skill-dependency-checklist)
3. [Common Deployment Errors](#common-deployment-errors)
4. [Debug Logs and Monitoring](#debug-logs-and-monitoring)
5. [Governor Limit Debugging](#governor-limit-debugging)
6. [Test Failures](#test-failures)

---

## LSP-Based Validation (Auto-Fix Loop)

The sf-apex skill includes Language Server Protocol (LSP) integration for real-time syntax validation. This enables Claude to automatically detect and fix Apex syntax errors during code authoring.

### How It Works

1. **PostToolUse Hook**: After every Write/Edit operation on `.cls` or `.trigger` files, the LSP hook validates syntax
2. **Apex Language Server**: Uses Salesforce's official `apex-jorje-lsp.jar` (from VS Code extension)
3. **Auto-Fix Loop**: If errors are found, Claude receives diagnostics and auto-fixes them (max 3 attempts)
4. **Two-Layer Validation**:
   - **LSP Validation**: Fast syntax checking (~500ms)
   - **150-Point Validation**: Semantic analysis for best practices

---

### Prerequisites

For LSP validation to work, users must have:

| Requirement | How to Install |
|-------------|----------------|
| **VS Code Salesforce Extension Pack** | VS Code → Extensions → "Salesforce Extension Pack" |
| **Java 11+ (Adoptium recommended)** | https://adoptium.net/temurin/releases/ |

**Verify Installation:**
```bash
# Check VS Code extensions
code --list-extensions | grep salesforce

# Check Java version
java -version
# Should output: openjdk version "11.x.x" or higher
```

---

### Validation Flow

```
User writes Apex code → Write/Edit tool executes
                              ↓
                    ┌─────────────────────────┐
                    │   LSP Validation (fast) │
                    │   Syntax errors only    │
                    └─────────────────────────┘
                              ↓
                    ┌─────────────────────────┐
                    │  150-Point Validation   │
                    │  Semantic best practices│
                    └─────────────────────────┘
                              ↓
                    Claude sees any errors and auto-fixes
```

---

### Sample LSP Error Output

```
============================================================
🔍 APEX LSP VALIDATION RESULTS
   File: force-app/main/default/classes/MyClass.cls
   Attempt: 1/3
============================================================

Found 1 error(s), 0 warning(s)

ISSUES TO FIX:
----------------------------------------
❌ [ERROR] line 4: Missing ';' at 'System.debug' (source: apex)

ACTION REQUIRED:
Please fix the Apex syntax errors above and try again.
(Attempt 1/3)
============================================================
```

---

### Common LSP Errors

| Error | Cause | Fix |
|-------|-------|-----|
| Missing ';' at ... | Statement not terminated | Add semicolon at end of line |
| Unexpected token ... | Syntax error | Check brackets, quotes, keywords |
| Unknown type ... | Class/type not found | Ensure class exists, check spelling |
| Method does not exist ... | Method call on wrong type | Verify method name and signature |
| Variable not found ... | Undeclared variable | Declare variable before use |

**Example Auto-Fix Loop:**

**Attempt 1 (ERROR):**
```apex
public class MyClass {
    public void doSomething() {
        System.debug('Hello')  // Missing semicolon
    }
}
```

**LSP Output:**
```
❌ [ERROR] line 3: Missing ';' at '}'
```

**Attempt 2 (SUCCESS):**
```apex
public class MyClass {
    public void doSomething() {
        System.debug('Hello');  // Fixed!
    }
}
```

**LSP Output:**
```
✅ VALIDATION PASSED
```

---

### Graceful Degradation

If LSP is unavailable (no VS Code extension or Java), validation silently skips - the skill continues to work with only 150-point semantic validation.

**Detection Logic:**
```python
# hooks/scripts/post-tool-validate.py
try:
    result = run_lsp_validation(file_path)
    if result.has_errors:
        print_errors(result)
except LSPNotAvailableException:
    # Silent fallback - continue without LSP
    pass
```

---

### Manual LSP Validation

**Run LSP validation manually from VS Code:**

1. Open Apex class in VS Code
2. View → Problems panel (`Cmd+Shift+M` / `Ctrl+Shift+M`)
3. See syntax errors highlighted in real-time

**Run from CLI (if available):**
```bash
# This requires Salesforce CLI with Apex Language Server
sf apex compile --file force-app/main/default/classes/MyClass.cls
```

---

## Cross-Skill Dependency Checklist

**Before deploying Apex code, verify these prerequisites:**

| Prerequisite | Check Command | Required For |
|--------------|---------------|--------------|
| **TAF Package** | `sf package installed list --target-org alias` | TAF trigger pattern |
| **Custom Fields** | `sf sobject describe --sobject Lead --target-org alias` | Field references in code |
| **Permission Sets** | `sf org list metadata --metadata-type PermissionSet` | FLS for custom fields |
| **Trigger_Action__mdt** | Check Setup → Custom Metadata Types | TAF trigger execution |
| **Named Credentials** | Check Setup → Named Credentials | External callouts |
| **Custom Settings** | Check Setup → Custom Settings | Bypass flags, configuration |

---

### Common Deployment Order

```
1. sf-metadata: Create custom fields
   └─> sf sobject create --sobject-name Lead --fields "Score__c:Number(3,0)"

2. sf-metadata: Create Permission Sets
   └─> Grant FLS on custom fields

3. sf-deploy: Deploy fields + Permission Sets
   └─> sf project deploy start --metadata-dir force-app/main/default/objects

4. sf-apex: Deploy Apex classes/triggers
   └─> sf project deploy start --metadata-dir force-app/main/default/classes

5. sf-data: Create test data
   └─> sf data create record --sobject Account --values "Name='Test'"
```

---

### Verifying Prerequisites

**Check TAF Package:**
```bash
sf package installed list --target-org myorg --json
```

**Output:**
```json
{
  "result": [
    {
      "Id": "04t...",
      "SubscriberPackageName": "Trigger Actions Framework",
      "SubscriberPackageVersionNumber": "1.2.0"
    }
  ]
}
```

**If not installed:**
```bash
sf package install --package 04tKZ000000gUEFYA2 --target-org myorg --wait 10
```

---

**Check Custom Metadata Records:**
```bash
sf data query --query "SELECT DeveloperName, Object__c, Apex_Class_Name__c FROM Trigger_Action__mdt" --target-org myorg
```

**Expected Output:**
```
DeveloperName          Object__c  Apex_Class_Name__c
─────────────────────────────────────────────────────
TA_Account_SetDefaults  Account    TA_Account_SetDefaults
TA_Lead_CalculateScore  Lead       TA_Lead_CalculateScore
```

**If missing, create via sf-metadata skill.**

---

## Common Deployment Errors

### Error: "Field does not exist"

**Cause**: Apex references a custom field that doesn't exist in target org.

**Example:**
```
Error: Field Account.Custom_Field__c does not exist
```

**Fix:**
1. Verify field exists:
   ```bash
   sf sobject describe --sobject Account --target-org myorg | grep Custom_Field__c
   ```

2. Deploy field first:
   ```bash
   sf project deploy start --metadata CustomField:Account.Custom_Field__c --target-org myorg
   ```

3. Then deploy Apex

---

### Error: "Invalid type: TriggerAction"

**Cause**: TAF package not installed in target org.

**Example:**
```
Error: Invalid type: TriggerAction.BeforeInsert
```

**Fix:**
```bash
# Install TAF package
sf package install --package 04tKZ000000gUEFYA2 --target-org myorg --wait 10

# Verify
sf package installed list --target-org myorg
```

---

### Error: "Insufficient access rights"

**Cause**: Deploy user lacks permissions.

**Example:**
```
Error: Insufficient access rights on object id
```

**Fix:**
1. Verify user has "Modify All Data" or is System Administrator
2. Or add specific permissions to user's profile:
   ```bash
   sf org assign permset --name "Deploy_Permissions" --target-org myorg
   ```

---

### Error: "Test coverage less than 75%"

**Cause**: Production deployment requires 75% test coverage.

**Example:**
```
Error: Average test coverage across all Apex Classes and Triggers is 68%, at least 75% required
```

**Fix:**
1. Identify uncovered classes:
   ```bash
   sf apex run test --code-coverage --result-format human --target-org myorg
   ```

2. Add missing test classes

3. Ensure tests have assertions:
   ```apex
   Assert.areEqual(expected, actual, 'Message');
   ```

---

### Error: "FIELD_CUSTOM_VALIDATION_EXCEPTION"

**Cause**: Apex code violates validation rule.

**Example:**
```
Error: FIELD_CUSTOM_VALIDATION_EXCEPTION: Annual Revenue must be greater than 0
```

**Fix:**
1. Check validation rules:
   ```bash
   sf data query --query "SELECT ValidationName, ErrorDisplayField, ErrorMessage FROM ValidationRule WHERE EntityDefinition.QualifiedApiName = 'Account'" --target-org myorg
   ```

2. Update Apex to satisfy validation logic:
   ```apex
   acc.AnnualRevenue = 1000000;  // Ensure > 0
   ```

---

## Debug Logs and Monitoring

### Enable Debug Logs

**Via Setup:**
1. Setup → Debug Logs
2. Click "New"
3. Select User
4. Set expiration (max 24 hours)
5. Set log levels:
   - Apex Code: `DEBUG`
   - Database: `INFO`
   - Workflow: `INFO`

**Via CLI:**
```bash
# Create trace flag
sf data create record --sobject TraceFlag --values "StartDate=2025-01-01T00:00:00Z EndDate=2025-01-02T00:00:00Z LogType=USER_DEBUG TracedEntityId=<USER_ID> DebugLevelId=<DEBUG_LEVEL_ID>" --target-org myorg

# Tail logs in real-time
sf apex tail log --target-org myorg
```

---

### Reading Debug Logs

**Structure:**
```
HH:MM:SS.SSS|EXECUTION_STARTED
HH:MM:SS.SSS|CODE_UNIT_STARTED|AccountService
HH:MM:SS.SSS|USER_DEBUG|[3]|DEBUG|Processing account: Test
HH:MM:SS.SSS|SOQL_EXECUTE_BEGIN|[5]|SELECT Id FROM Account
HH:MM:SS.SSS|SOQL_EXECUTE_END|[5]|Rows:10
HH:MM:SS.SSS|DML_BEGIN|[8]|Op:Update|Type:Account|Rows:10
HH:MM:SS.SSS|DML_END|[8]
HH:MM:SS.SSS|LIMIT_USAGE_FOR_NS|(default)|SOQL:1/100|DML:1/150
HH:MM:SS.SSS|EXECUTION_FINISHED
```

**Key Events:**
- `USER_DEBUG`: Your `System.debug()` statements
- `SOQL_EXECUTE_*`: SOQL queries
- `DML_BEGIN/END`: DML operations
- `LIMIT_USAGE_FOR_NS`: Governor limit consumption

---

### Strategic Debug Statements

```apex
public static void processAccounts(List<Account> accounts) {
    System.debug(LoggingLevel.INFO, '=== START processAccounts ===');
    System.debug(LoggingLevel.INFO, 'Input size: ' + accounts.size());

    // Log limits BEFORE expensive operation
    System.debug('SOQL before: ' + Limits.getQueries() + '/' + Limits.getLimitQueries());

    List<Contact> contacts = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds];

    // Log limits AFTER
    System.debug('SOQL after: ' + Limits.getQueries() + '/' + Limits.getLimitQueries());
    System.debug('Contacts retrieved: ' + contacts.size());

    System.debug(LoggingLevel.INFO, '=== END processAccounts ===');
}
```

---

### Log Levels

| Level | When to Use | Example |
|-------|-------------|---------|
| `ERROR` | Critical failures | `System.debug(LoggingLevel.ERROR, 'DML failed: ' + e.getMessage())` |
| `WARN` | Potential issues | `System.debug(LoggingLevel.WARN, 'No contacts found for account')` |
| `INFO` | Key milestones | `System.debug(LoggingLevel.INFO, 'Processing 251 accounts')` |
| `DEBUG` | Detailed traces | `System.debug(LoggingLevel.DEBUG, 'Variable value: ' + var)` |
| `FINE`/`FINER`/`FINEST` | Very detailed | Rarely used |

---

## Governor Limit Debugging

### Monitoring Limits in Code

```apex
public static void expensiveOperation() {
    System.debug('=== LIMIT CHECK ===');
    System.debug('SOQL Queries: ' + Limits.getQueries() + '/' + Limits.getLimitQueries());
    System.debug('DML Statements: ' + Limits.getDmlStatements() + '/' + Limits.getLimitDmlStatements());
    System.debug('DML Rows: ' + Limits.getDmlRows() + '/' + Limits.getLimitDmlRows());
    System.debug('CPU Time: ' + Limits.getCpuTime() + '/' + Limits.getLimitCpuTime());
    System.debug('Heap Size: ' + Limits.getHeapSize() + '/' + Limits.getLimitHeapSize());
}
```

---

### Common Limit Exceptions

**SOQL Limit (100 queries):**
```
System.LimitException: Too many SOQL queries: 101
```

**Fix**: Query BEFORE loops, use Maps for lookups.

**DML Limit (150 statements):**
```
System.LimitException: Too many DML statements: 151
```

**Fix**: Collect records in List, DML AFTER loop.

**CPU Time Limit (10 seconds):**
```
System.LimitException: Maximum CPU time exceeded
```

**Fix**: Optimize loops, move expensive operations to async, reduce complexity.

**Heap Size Limit (6 MB):**
```
System.LimitException: Apex heap size too large
```

**Fix**: Process in batches, clear collections when done, avoid storing large objects in memory.

---

### Using Limits Class for Alerts

```apex
public static void monitoredOperation() {
    // Warn if approaching 80% of limit
    Integer queriesUsed = Limits.getQueries();
    Integer queriesLimit = Limits.getLimitQueries();

    if (queriesUsed > queriesLimit * 0.8) {
        System.debug(LoggingLevel.WARN, 'Approaching SOQL limit: ' + queriesUsed + '/' + queriesLimit);
    }

    // Expensive operation
    List<Account> accounts = [SELECT Id FROM Account];
}
```

---

## Test Failures

### Common Test Failure Patterns

**Pattern 1: No assertions**
```apex
@IsTest
static void testCreateAccount() {
    Account acc = new Account(Name = 'Test');
    insert acc;
    // PASSES even if logic is broken!
}
```

**Fix**: Add assertions
```apex
@IsTest
static void testCreateAccount() {
    Account acc = new Account(Name = 'Test', Industry = 'Tech');
    insert acc;

    Account inserted = [SELECT Id, Industry FROM Account WHERE Id = :acc.Id];
    Assert.areEqual('Tech', inserted.Industry, 'Industry should be set');
}
```

---

**Pattern 2: Order dependency**
```apex
@IsTest
static void test1() {
    insert new Account(Name = 'Shared');
}

@IsTest
static void test2() {
    // Assumes test1 ran first - BRITTLE!
    Account acc = [SELECT Id FROM Account WHERE Name = 'Shared'];
}
```

**Fix**: Use @TestSetup or create data in each test
```apex
@TestSetup
static void setup() {
    insert new Account(Name = 'Shared');
}

@IsTest
static void test2() {
    Account acc = [SELECT Id FROM Account WHERE Name = 'Shared'];  // Safe
}
```

---

**Pattern 3: Insufficient permissions**
```apex
@IsTest
static void testRestrictedUser() {
    User u = TestDataFactory.createStandardUser();

    System.runAs(u) {
        // Fails if user lacks permission
        insert new Account(Name = 'Test');
    }
}
```

**Fix**: Grant necessary permissions
```apex
@TestSetup
static void setup() {
    User u = TestDataFactory.createStandardUser();
    insert new PermissionSetAssignment(
        AssigneeId = u.Id,
        PermissionSetId = [SELECT Id FROM PermissionSet WHERE Name = 'Account_Create'].Id
    );
}
```

---

### Running Tests

**VS Code:**
1. Open test class
2. Click "Run Test" above `@IsTest` method
3. View results in Output panel

**CLI:**
```bash
# Run specific test class
sf apex run test --tests AccountServiceTest --result-format human --code-coverage --target-org myorg

# Run all tests
sf apex run test --test-level RunLocalTests --result-format human --code-coverage --target-org myorg

# Run tests and generate coverage report
sf apex run test --test-level RunLocalTests --code-coverage --result-format json --output-dir test-results --target-org myorg
```

**Output:**
```
Test Summary
════════════
Outcome              Passed
Tests Ran            12
Pass Rate            100%
Fail Rate            0%
Skip Rate            0%
Test Run Coverage    92%
Org Wide Coverage    85%
Test Execution Time  1234 ms

Coverage Warnings
═════════════════
AccountService.cls  Line 45 not covered by tests
```

---

## Debugging Strategies

### 1. Binary Search for Errors

When unsure where error occurs, add debug statements at midpoints:

```apex
public static void complexOperation() {
    System.debug('START');

    // Part 1
    List<Account> accounts = [SELECT Id FROM Account];
    System.debug('CHECKPOINT 1: Retrieved ' + accounts.size() + ' accounts');

    // Part 2
    for (Account acc : accounts) {
        acc.Industry = 'Tech';
    }
    System.debug('CHECKPOINT 2: Updated accounts');

    // Part 3
    update accounts;
    System.debug('CHECKPOINT 3: DML complete');

    System.debug('END');
}
```

Run and check logs to see which checkpoint fails.

---

### 2. Isolate in Anonymous Apex

**Execute in Developer Console:**
```apex
Account acc = new Account(Name = 'Debug Test', Industry = 'Tech');
insert acc;

System.debug('Account ID: ' + acc.Id);
System.debug('Industry: ' + acc.Industry);
```

Open Execute Anonymous Window (`Ctrl+E`), paste code, check logs.

---

### 3. Unit Test in Isolation

**Create minimal test case:**
```apex
@IsTest
static void debugIssue() {
    Account acc = new Account(Name = 'Test', AnnualRevenue = null);

    Test.startTest();
    AccountService.calculateScore(acc);  // Isolated method
    Test.stopTest();

    System.debug('Score: ' + acc.Score__c);
}
```

Easier to debug than full integration test.

---

## Reference

**Full Documentation**: See `docs/` folder for comprehensive guides:
- `best-practices.md` - Debugging best practices
- `testing-guide.md` - Test troubleshooting
- `code-review-checklist.md` - Quality checklist

**Back to Main**: [SKILL.md](../SKILL.md)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.