Troubleshooting Guide
Common issues and solutions for Agentforce session tracing extraction.
Authentication Issues
401 Unauthorized
Symptom:
RuntimeError: Token exchange failed: invalid_grant
Causes & Solutions:
| Cause | Solution |
|---|---|
| Expired JWT | Check certificate expiration with openssl x509 -enddate -noout -in cert.crt |
| Wrong consumer key | Verify consumer key matches External Client App |
| Certificate mismatch | Re-upload certificate to Salesforce |
| User not authorized | Assign user to Connected App / Permission Set |
Debug Steps:
# Test JWT generation
python3 -c "
from scripts.auth import DataCloudAuth
auth = DataCloudAuth('myorg', 'CONSUMER_KEY')
print(auth.get_token()[:50])
"
# Verify org connection
sf org display --target-org myorg --json
403 Forbidden
Symptom:
RuntimeError: Access denied: Ensure ECA has cdp_query_api scope
Solutions:
Add Required Scopes to External Client App:
cdp_query_apicdp_profile_api
Assign Data 360 Permissions to user:
- Setup → Permission Sets → Data 360 permissions
Enable Data 360 in org:
- Setup → Data 360 → Enable
Data Issues
No Session Data Found
Symptom:
Extracted 0 sessions
Causes & Solutions:
| Cause | Solution |
|---|---|
| Session tracing not enabled | Setup → Agentforce → Enable Session Tracing |
| Wrong date range | Data typically lags 5-15 minutes |
| Wrong agent name | Check exact API name with sf agent list |
| Sandbox without data | Session tracing may not be enabled in sandbox |
Debug:
# Check if DMO exists and has data
from scripts.datacloud_client import Data360Client
client = Data360Client(auth)
count = client.count("ssot__AIAgentSession__dlm")
print(f"Total sessions in Data 360: {count}")
Query Timeout
Symptom:
RuntimeError: Request timed out after 3 retries
Solutions:
Add date filters to reduce data volume:
extractor.extract_sessions( since=datetime.now() - timedelta(days=1), # Shorter range )Use incremental extraction:
python3 scripts/cli.py extract-incremental --org prodIncrease timeout:
client = DataCloudClient(auth, timeout=300.0) # 5 minutes
Memory Error
Symptom:
MemoryError: Unable to allocate array
Solutions:
Use lazy evaluation:
# Good sessions = pl.scan_parquet(path) result = sessions.filter(...).collect() # Bad sessions = pl.read_parquet(path) # Loads everythingStream to Parquet instead of loading:
client.query_to_parquet(sql, output_path) # Streams, doesn't load allProcess in batches:
for i in range(0, total_sessions, 1000): batch_ids = session_ids[i:i+1000] # Process batch
Extraction Issues
Missing Child Records
Symptom:
Sessions: 1000
Interactions: 0
Steps: 0
Cause: Session IDs not matching in child queries.
Solution:
# Verify session IDs are valid
sessions_df = pl.read_parquet(data_dir / "sessions" / "data.parquet")
print(sessions_df.head()) # Check ssot__Id__c values
# Check if interactions exist for these sessions
interaction_query = f"""
SELECT COUNT(*) FROM ssot__AIAgentInteraction__dlm
WHERE ssot__AiAgentSessionId__c IN ('{session_ids[0]}')
"""
Parquet Write Failure
Symptom:
ArrowInvalid: Could not convert X with type Y
Solutions:
Check for nested/complex types:
# Complex types are serialized to JSON strings if isinstance(value, (dict, list)): value = json.dumps(value)Use explicit schema:
from scripts.models import SCHEMAS client.query_to_parquet(sql, path, schema=SCHEMAS["sessions"])
Analysis Issues
Polars Import Error
Symptom:
ImportError: No module named 'polars'
Solution:
pip install polars pyarrow
Empty DataFrame
Symptom:
analyzer.session_summary() # Returns empty DataFrame
Debug:
# Check if files exist
from pathlib import Path
data_dir = Path("./stdm_data")
print(list(data_dir.glob("**/*.parquet")))
# Check if files have data
import pyarrow.parquet as pq
pf = pq.ParquetFile(data_dir / "sessions" / "data.parquet")
print(f"Rows: {pf.metadata.num_rows}")
Column Not Found
Symptom:
SchemaError: column 'ssot__Id__c' not found
Cause: Parquet file has different column names.
Debug:
# Check actual column names
import pyarrow.parquet as pq
pf = pq.ParquetFile("path/to/file.parquet")
print(pf.schema_arrow)
CLI Issues
Command Not Found
Symptom:
bash: stdm-extract: command not found
Solution:
# Run directly
python3 scripts/cli.py extract --help
# Or install as package (if setup.py exists)
pip install -e .
Environment Variable Not Set
Symptom:
ValueError: Consumer key not found. Set SF_CONSUMER_KEY
Solutions:
Set environment variable:
export SF_CONSUMER_KEY="3MVG9..."Pass via command line:
python3 scripts/cli.py extract --org prod --consumer-key "3MVG9..."Create
.envfile (if using python-dotenv):SF_CONSUMER_KEY=3MVG9...
Data 360 Specific Issues
DMO Not Found
Symptom:
Error: Object ssot__AIAgentSession__dlm not found
Causes:
- Session tracing not enabled - Enable in Agentforce settings
- Wrong API version - Use v65.0 or higher
- Permission issue - User needs Data 360 access
Query Syntax Error
Symptom:
Error: Unexpected token at position X
Common fixes:
| Issue | Fix |
|---|---|
| Single quotes in values | Escape: 'O''Brien' |
| Reserved words | Use backticks: `Order` |
| Date format | Use ISO: '2026-01-28T00:00:00.000Z' |
Lessons Learned (Live Deployment - Jan 2026)
Critical discoveries from live testing against Vivint-DevInt org.
API Version: v65.0 Recommended
Problem: Documentation referenced v60.0, but Data 360 Query SQL API requires v64.0+. We recommend v65.0 (Winter '26).
Fix:
# Wrong (v60.0)
url = f"{instance_url}/services/data/v60.0/ssot/querybuilder/execute"
# Correct (v65.0)
url = f"{instance_url}/services/data/v65.0/ssot/query-sql"
Field Naming: AiAgent (lowercase 'i')
Problem: Documentation shows AIAgent but actual schema uses AiAgent.
Wrong:
SELECT ssot__AIAgentSessionId__c FROM ssot__AIAgentInteraction__dlm
Correct:
SELECT ssot__AiAgentSessionId__c FROM ssot__AIAgentInteraction__dlm
Affected fields: All FK references in Interaction, Step, and Moment DMOs.
AIAgentMoment Links to Sessions, Not Interactions
Problem: Documentation implied Moments link to Interactions via AIAgentInteractionId__c.
Reality: AIAgentMoment links directly to Sessions via ssot__AiAgentSessionId__c.
Correct Schema:
AIAgentSession → AIAgentInteraction → AIAgentInteractionStep
↓
AIAgentMoment (links to session, not interaction)
Response Format: Array of Arrays
Problem: Expected array of objects, but v64.0+ returns array of arrays.
v65.0 Response:
{
"metadata": [{"name": "ssot__Id__c"}, {"name": "ssot__Name__c"}],
"data": [
["019abc...", "Session 1"],
["019def...", "Session 2"]
]
}
Fix: Convert using metadata column names:
column_names = [col["name"] for col in metadata]
records = [dict(zip(column_names, row)) for row in data]
External Client App Setup URL
Problem: Documentation had wrong Setup URL.
Wrong: /lightning/setup/ExternalClientAppManager/home
Correct: /lightning/setup/ManageExternalClientApplication/home
Incremental Extraction Overwrites Data
Problem: extract-incremental was overwriting Parquet files instead of appending.
Symptoms:
- Running incremental after full extract → lost all historical data
- Session count dropped from 447 to 17
Fix: Added append + dedupe_key parameters to query_to_parquet():
# Now correctly reads existing, appends new, dedupes by ID
result = client.query_to_parquet(
sql, output_path,
append=True,
dedupe_key="ssot__Id__c"
)
Session End Types All NOT_SET
Observation: 100% of sessions had ssot__AiAgentSessionEndType__c = 'NOT_SET'.
Possible causes:
- Sessions not explicitly closed
- Agent Builder sessions don't track end types
- Potential data quality issue in source org
Recommendation: Investigate session closure patterns in agent configuration.
Getting Help
Debug Mode
# Enable verbose logging
python3 scripts/cli.py extract --org prod --verbose 2>&1 | tee debug.log
Check Data 360 Status
# List available DMOs
python3 -c "
from scripts.auth import Data360Auth
from scripts.datacloud_client import Data360Client
auth = Data360Auth('prod', 'KEY')
client = Data360Client(auth)
dmos = client.list_dmos()
for dmo in dmos:
print(dmo.get('name'))
"
Report Issues
If you encounter issues not covered here:
- Enable verbose mode and capture logs
- Note the error message and stack trace
- Check Data 360 health status
- Contact Salesforce support for API issues