Troubleshooting Guide¶
This guide covers common issues and their solutions when working with Centrali.
Authentication Issues¶
"Invalid client credentials" Error¶
Symptom:
Common Causes:
- Incorrect credentials
- Typo in
client_idorclient_secret - Extra spaces or newlines in environment variables
-
Using credentials from wrong workspace
-
Service account deleted or rotated
- Credentials were invalidated
Solutions:
# Check for whitespace
echo "[$CENTRALI_CLIENT_ID]" # Should have no spaces around it
echo "[$CENTRALI_CLIENT_SECRET]"
# Verify credentials in dashboard
# Settings → Service Accounts → Check your service account exists
# Test credentials manually
curl -X POST "https://auth.centrali.io/oidc/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$CENTRALI_CLIENT_ID" \
-d "client_secret=$CENTRALI_CLIENT_SECRET" \
-d "scope=openid"
If still failing: - Create a new service account - Ensure you're using credentials from the correct workspace - Check that service account wasn't revoked
"Token expired" Error¶
Symptom:
Cause: JWT tokens expire after 7 hours.
Solution:
With SDK (automatic):
// SDK handles this automatically - no action needed
const centrali = new CentraliSDK({ clientId, clientSecret, ... });
Manual implementation:
let tokenCache = null;
let tokenExpiry = null;
async function getToken() {
if (tokenCache && Date.now() < tokenExpiry) {
return tokenCache;
}
const response = await fetch('https://auth.centrali.io/oidc/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.CENTRALI_CLIENT_ID,
client_secret: process.env.CENTRALI_CLIENT_SECRET,
scope: 'openid'
})
});
const data = await response.json();
tokenCache = data.access_token;
// Refresh 5 min before expiration
tokenExpiry = Date.now() + ((data.expires_in - 300) * 1000);
return tokenCache;
}
Missing Authorization Header¶
Symptom:
Solution:
# ❌ Wrong
curl https://api.centrali.io/data/workspace/my-workspace/api/v1/structures
# ✅ Correct
curl https://api.centrali.io/data/workspace/my-workspace/api/v1/structures \
-H "Authorization: Bearer YOUR_TOKEN"
Data & Record Issues¶
Validation Errors When Creating Records¶
Symptom:
{
"error": "Validation Failed",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
Common Causes:
-
Wrong data type
-
Missing required fields
-
Invalid format
-
Violating constraints
Solution: - Check structure definition in dashboard - Validate data before sending to API - Read error details for specific field issues
"Structure not found" Error¶
Symptom:
Causes: - Structure ID doesn't exist - Wrong workspace - Structure was deleted
Solutions:
# List all structures in workspace
curl https://api.centrali.io/data/workspace/YOUR_WORKSPACE/api/v1/structures \
-H "Authorization: Bearer $TOKEN"
# Verify you're using correct workspace
echo $CENTRALI_WORKSPACE
# Check structure ID in dashboard
# Dashboard → Structures → Copy ID
"Record not found" Error¶
Symptom:
Causes: - Record ID doesn't exist - Record was deleted - Wrong workspace - No permission to access
Solutions:
// Verify record exists
try {
const record = await centrali.getRecord('Product', 'rec_xyz');
} catch (error) {
if (error.response?.status === 404) {
console.log('Record does not exist');
// Handle gracefully
}
}
// Query to find records instead
const records = await centrali.queryRecords('Product', {
filter: 'slug = "my-product"'
});
Function Issues¶
Function Not Triggering¶
Symptom: Function code exists but doesn't execute when expected.
Checklist:
-
Verify trigger is active
-
Check trigger conditions
-
Check function status
-
View function logs
Function Timing Out¶
Symptom:
Cause: Function execution limit is 30 seconds.
Solutions:
-
Optimize slow operations
// ❌ Processing too many records exports.handler = async (event, context) => { const allRecords = await centrali.records.query({ limit: 10000 }); for (const record of allRecords) { await processRecord(record); // Sequential! } }; // ✅ Batch processing with limits exports.handler = async (event, context) => { const records = await centrali.records.query({ limit: 100 }); // Process in parallel (faster) await Promise.all(records.map(processRecord)); return { processed: records.length }; }; -
Break into smaller chunks
// Chain multiple function executions exports.handler = async (event, context) => { const { offset = 0 } = event.data; const limit = 100; const records = await centrali.records.query({ limit, offset }); await processRecords(records); // If more to process, trigger another run if (records.length === limit) { await centrali.functions.invoke('processBatch', { offset: offset + limit }); } return { processed: records.length }; };
Function Returns Error¶
Symptom: Function executes but returns error in logs.
Debugging:
-
Check function logs
-
Common issues:
- Missing environment variables
- External API errors
-
Invalid data access
-
Add logging
exports.handler = async (event, context) => { console.log('Event:', JSON.stringify(event)); console.log('Context workspace:', context.workspace); try { const result = await someOperation(); console.log('Result:', result); return { success: true, data: result }; } catch (error) { console.error('Error:', error.message); console.error('Stack:', error.stack); throw error; } };
Query Issues¶
Query Returns No Results¶
Symptom: Query executes but returns empty array when you expect results.
Debugging:
-
Simplify the query
-
Check filter syntax
-
Verify field names
"Query too complex" Error¶
Symptom:
Cause: Query has too many operations, filters, or nested includes.
Solution:
// ❌ Too complex
const query = `
FROM Product
WHERE condition1 AND condition2 AND condition3 ... (50+ conditions)
INCLUDE category FROM Category
INCLUDE tags FROM Tag
INCLUDE reviews FROM Review
INCLUDE manufacturer FROM Company
INCLUDE ... (many includes)
`;
// ✅ Simplify
const products = await centrali.queryRecords('Product', {
filter: 'category = "electronics" AND inStock = true',
limit: 100
});
// Fetch related data separately
for (const product of products) {
product.reviews = await centrali.queryRecords('Review', {
filter: `productId = "${product.id}"`
});
}
Connection & Network Issues¶
Request Timeout¶
Symptom: Request hangs or times out.
Solutions:
-
Check network connectivity
-
Increase timeout (SDK)
-
Check firewall/proxy
- Ensure outbound HTTPS (443) is allowed
- Check corporate proxy settings
Rate Limit Errors¶
Symptom:
Solutions:
-
Implement rate limit handling
async function makeRequestWithRetry(fn) { try { return await fn(); } catch (error) { if (error.response?.status === 429) { const retryAfter = parseInt(error.response.headers['retry-after']) || 60; console.log(`Rate limited. Waiting ${retryAfter}s...`); await new Promise(r => setTimeout(r, retryAfter * 1000)); return await fn(); } throw error; } } -
Optimize API usage
- Use bulk operations instead of loops
- Cache responses
-
Use webhooks instead of polling
-
Check rate limit headers
See Limits & Quotas for details.
Dashboard & Web Console Issues¶
Can't Access Dashboard¶
Solutions:
- Clear browser cache and cookies
- Try incognito/private mode
- Check for browser extension conflicts
- Try a different browser
Lost Service Account Secret¶
Symptom: Can't find client_secret after creation.
Solution: - Secrets are shown only once during creation - Cannot retrieve - must rotate to get new secret - Dashboard → Settings → Service Accounts → [Your Account] → Rotate Secret - Update your application with new secret immediately
Getting More Help¶
Before Contacting Support¶
Gather this information:
-
Request ID (from error response)
-
Workspace slug
- Timestamp of issue
- Steps to reproduce
- Error message and status code
Check Centrali Status¶
- Visit status.centrali.io (if available)
- Check for scheduled maintenance
- Subscribe to status updates
Contact Support¶
- Email: support@centrali.io
- Dashboard: Settings → Support → New Ticket
- Include request ID and details above
Related Documentation¶
- Error Handling Guide - Error codes and handling
- Authentication Overview - Auth flows
- Limits & Quotas - Platform limits
- Account Setup - Initial setup
Quick Reference¶
Most Common Issues¶
| Issue | Quick Fix |
|---|---|
| "Invalid credentials" | Check for typos, spaces in env vars |
| "Token expired" | SDK handles automatically, or fetch new token |
| Validation error | Check structure definition, verify data types |
| Function not triggering | Verify trigger is active and conditions met |
| Function timeout | Reduce processing, break into chunks |
| Rate limited | Implement retry with backoff, optimize requests |
| Record not found | Verify ID and workspace are correct |
Useful Commands¶
# Test authentication
curl -X POST "https://auth.centrali.io/oidc/token" \
-d "grant_type=client_credentials" \
-d "client_id=$CENTRALI_CLIENT_ID" \
-d "client_secret=$CENTRALI_CLIENT_SECRET" \
-d "scope=openid"
# List structures
curl "https://api.centrali.io/data/workspace/$WORKSPACE/api/v1/structures" \
-H "Authorization: Bearer $TOKEN"
# Test connectivity
curl -I https://centrali.io