Troubleshooting Guide¶
This guide helps you diagnose and resolve common issues across all Smartsheet Integration repositories.
Quick Diagnostic Table¶
| Symptom | Possible Cause | Quick Fix | Full Solution |
|---|---|---|---|
| 403 Forbidden | Invalid/expired token | Check token | Authentication Issues |
| 429 Rate Limit | Too many API calls | Wait 60s | Rate Limiting |
| Connection timeout | Network/firewall | Check network | Connection Issues |
| No data synced | Column ID mismatch | Verify IDs | Data Sync Issues |
| Duplicate rows | Bad unique key | Check upsert logic | Duplicate Data |
| Import fails | Missing dependencies | pip install -r requirements.txt | Runtime Errors |
| Script hangs | API timeout | Increase timeout | Performance Issues |
| Wrong data | Column mapping error | Check mappings | Data Integrity |
Connection Issues¶
Cannot Connect to Smartsheet API¶
Symptoms:
Diagnostic Steps:
-
Check Internet Connection
-
Verify API Endpoint
-
Check Firewall/Proxy
Solutions:
-
Corporate Network: Configure proxy settings
-
VPN Issues: Ensure VPN allows API access
- DNS Issues: Try using IP address or alternate DNS
Cannot Connect to Supabase¶
Symptoms:
Diagnostic Steps:
-
Verify Supabase URL
-
Check Credentials
from supabase import create_client url = os.environ['SUPABASE_URL'] key = os.environ['SUPABASE_KEY'] try: client = create_client(url, key) # Test query response = client.table('test').select('*').limit(1).execute() print("Connection successful") except Exception as e: print(f"Connection failed: {e}")
Solutions:
- Invalid URL: Check project URL in Supabase dashboard
- Wrong Key: Use
service_rolekey, notanonkey for server-side - Network Issues: Check firewall rules
SSL Certificate Errors¶
Symptoms:
Solutions:
# Temporary workaround (NOT recommended for production)
import ssl
import certifi
# Use certifi certificates
import smartsheet
client = smartsheet.Smartsheet(api_token)
# Or update CA certificates
# Ubuntu/Debian
sudo apt-get install ca-certificates
sudo update-ca-certificates
# MacOS
pip install --upgrade certifi
Authentication Issues¶
Invalid or Expired API Token¶
Symptoms:
ApiError: 1004 - You are not authorized to perform this action
ApiError: 1002 - Your access token is invalid
Diagnostic Steps:
-
Test Token
-
Check Token in Code
Solutions:
- Regenerate Token: Go to Smartsheet → Apps & Integrations → API Access
-
Check Environment: Ensure
.envfile is loaded -
Verify Token Format: Should start with
llor similar prefix
Insufficient Permissions¶
Symptoms:
Solutions:
- Check Sheet Sharing:
- Open sheet in Smartsheet
- Click Share
-
Verify user has Editor or Admin access
-
Use Admin Token: Generate token from account with appropriate permissions
-
Check Sheet ID: Ensure using correct sheet ID
Data Sync Issues¶
No Data Being Synced¶
Diagnostic Steps:
-
Verify Sheet Has Data
-
Check Column IDs
-
Enable Verbose Logging
Solutions:
- Column ID Mismatch: Update column IDs in
.env - Empty Rows: Check for filter conditions excluding all data
- Permission Issues: Verify read access to sheet
Data Not Updating¶
Symptoms: Script runs successfully but data doesn't change
Diagnostic Steps:
-
Check Dry-Run Mode
-
Verify Update Payload
-
Check for Formula Columns
Solutions:
- Disable Dry-Run: Set
DRY_RUN=false - Check Return Status: Look for errors in API response
- Verify Column Write Access: Can't write to formula or system columns
Stale Data¶
Symptoms: Syncs old data repeatedly, misses new changes
Solution: Implement incremental sync
import json
from datetime import datetime, timedelta
STATE_FILE = 'sync_state.json'
def get_last_sync_time():
try:
with open(STATE_FILE, 'r') as f:
state = json.load(f)
return datetime.fromisoformat(state['last_sync'])
except FileNotFoundError:
# First run - sync last 24 hours
return datetime.now() - timedelta(days=1)
def save_sync_time():
with open(STATE_FILE, 'w') as f:
json.dump({'last_sync': datetime.now().isoformat()}, f)
# Use in sync logic
last_sync = get_last_sync_time()
sheet = client.Sheets.get_sheet(
SHEET_ID,
rows_modified_since=last_sync
)
# Process rows...
save_sync_time()
Duplicate Data¶
Duplicate Rows Created¶
Diagnostic Steps:
-
Identify Duplicates
-
Check Upsert Logic
Solutions:
Option 1: Use External ID for Upsert
# When creating/updating rows
row = smartsheet.models.Row()
row.to_bottom = True
row.cells.append({
'column_id': COLUMN_ID_NAME,
'value': 'John Doe'
})
# Set external ID for upsert capability
row.external_id = f"user_{user_id}"
# Later, to upsert
row = smartsheet.models.Row()
row.external_id = f"user_{user_id}" # Same external ID
row.cells.append({'column_id': COLUMN_ID_NAME, 'value': 'Jane Doe'})
# This will update existing row with same external ID
Option 2: Query Before Insert
def row_exists(sheet_id, column_id, value):
sheet = client.Sheets.get_sheet(sheet_id)
for row in sheet.rows:
cell_value = get_cell_value(row, column_id)
if cell_value == value:
return row
return None
# Before inserting
existing_row = row_exists(SHEET_ID, COLUMN_ID_UNIQUE_KEY, new_value)
if existing_row:
# Update existing
update_row(existing_row.id, new_data)
else:
# Insert new
insert_row(new_data)
Option 3: Clean Up Duplicates
def remove_duplicates(sheet_id, column_id):
sheet = client.Sheets.get_sheet(sheet_id)
seen = {}
to_delete = []
for row in sheet.rows:
value = get_cell_value(row, column_id)
if value in seen:
# Keep older row, delete newer
to_delete.append(row.id)
else:
seen[value] = row.id
if to_delete:
print(f"Deleting {len(to_delete)} duplicate rows...")
client.Sheets.delete_rows(sheet_id, to_delete)
Runtime Errors¶
Module Not Found¶
Symptoms:
Solutions:
# Install dependencies
pip install -r requirements.txt
# Or specific packages
pip install smartsheet-python-sdk
pip install supabase
pip install python-dotenv
# For Node.js
npm install
Python Version Issues¶
Symptoms:
Solutions:
# Check Python version
python --version
python3 --version
# Should be 3.9+
# Use specific version
python3.9 main.py
# Or update Python
sudo apt install python3.9
Environment Variables Not Loading¶
Symptoms:
Solutions:
# Ensure .env is loaded
from dotenv import load_dotenv
load_dotenv() # Add at the very start
# Or specify .env path
load_dotenv('/path/to/.env')
# Verify loading
import os
print(f"Token loaded: {'SMARTSHEET_ACCESS_TOKEN' in os.environ}")
JSON Decode Error¶
Symptoms:
Diagnostic:
# Check API response
response = client.Sheets.get_sheet(SHEET_ID)
print(f"Response type: {type(response)}")
print(f"Response: {response}")
# If parsing JSON manually
try:
data = json.loads(response_text)
except json.JSONDecodeError as e:
print(f"Invalid JSON: {response_text[:200]}")
print(f"Error at position {e.pos}: {e.msg}")
Rate Limiting Errors¶
429 Too Many Requests¶
Symptoms:
Immediate Fix:
Long-term Solution:
import time
from smartsheet.exceptions import ApiError
def api_call_with_retry(func, max_retries=5):
for attempt in range(max_retries):
try:
return func()
except ApiError as e:
if e.error.result.status_code == 429:
wait_time = min(60 * (2 ** attempt), 300) # Cap at 5 minutes
logger.warning(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
else:
raise
raise Exception("Rate limit retries exceeded")
# Usage
result = api_call_with_retry(
lambda: client.Sheets.update_rows(sheet_id, rows)
)
Prevent Rate Limits:
-
Use Bulk Operations
-
Add Delays
-
Track Request Count
class RateLimiter: def __init__(self, max_per_minute=250): self.max_per_minute = max_per_minute self.requests = [] def wait_if_needed(self): now = time.time() # Remove requests older than 60 seconds self.requests = [t for t in self.requests if now - t < 60] if len(self.requests) >= self.max_per_minute: sleep_time = 60 - (now - self.requests[0]) logger.info(f"Rate limit protection: sleeping {sleep_time:.1f}s") time.sleep(sleep_time) self.requests = [] self.requests.append(time.time()) limiter = RateLimiter() # Before each API call limiter.wait_if_needed() client.Sheets.update_rows(sheet_id, rows)
Performance Issues¶
Slow Sync Times¶
Diagnostic:
import time
def timed_operation(name, func):
start = time.time()
result = func()
duration = time.time() - start
logger.info(f"{name} took {duration:.2f}s")
return result
# Usage
sheet = timed_operation(
"Fetch sheet",
lambda: client.Sheets.get_sheet(SHEET_ID)
)
timed_operation(
"Update rows",
lambda: client.Sheets.update_rows(SHEET_ID, rows)
)
Solutions:
-
Reduce Data Volume
-
Use Parallel Processing
-
Optimize Database Queries
Memory Issues¶
Symptoms:
Solutions:
-
Process in Batches
-
Use Generators
Data Integrity Issues¶
Wrong Data in Cells¶
Diagnostic:
# Check cell values and types
sheet = client.Sheets.get_sheet(SHEET_ID)
row = sheet.rows[0]
for cell in row.cells:
column = next(col for col in sheet.columns if col.id == cell.column_id)
print(f"{column.title}: {cell.value} (type: {type(cell.value)})")
Solutions:
-
Validate Before Writing
def validate_cell_value(column_type, value): if column_type == 'DATE': try: datetime.fromisoformat(str(value)) return True except ValueError: return False elif column_type == 'CHECKBOX': return isinstance(value, bool) return True # Use before updating if not validate_cell_value(column.type, new_value): logger.error(f"Invalid value {new_value} for column {column.title}") -
Handle Type Conversions
Debugging Tools¶
Enable Debug Logging¶
import logging
# Maximum verbosity
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Log API requests
import smartsheet
client = smartsheet.Smartsheet(token)
client.logger.setLevel(logging.DEBUG)
Inspect API Responses¶
# Capture raw response
response = client.Sheets.get_sheet(SHEET_ID)
# Print structure
import json
print(json.dumps(response.to_dict(), indent=2))
Test Connectivity Script¶
#!/bin/bash
# test_connectivity.sh
echo "Testing Smartsheet API..."
curl -H "Authorization: Bearer $SMARTSHEET_ACCESS_TOKEN" \
https://api.smartsheet.com/2.0/users/me
echo -e "\n\nTesting Supabase..."
curl "$SUPABASE_URL/rest/v1/"
echo -e "\n\nDone!"
Getting Further Help¶
If issues persist:
- Check Logs: Review application logs for detailed errors
- Enable Debug Mode: Use verbose logging
- Test Components: Test Smartsheet API, database, network separately
- Review Recent Changes: What changed before the issue started?
- Check Service Status:
- Smartsheet Status
- Supabase Status
Related Documentation¶
- Watch Out For - Common pitfalls
- Maintenance Guide - Update procedures
- Smartsheet Integration - Data flow details