Troubleshooting Guide¶
Solutions to common issues when using the Penfield API.
Authentication Issues¶
"Invalid credentials" (401)¶
Symptom:
{
"status": "error",
"error": {
"code": "AUTH_INVALID_CREDENTIALS",
"message": "Invalid credentials"
}
}
Causes: 1. Wrong API key format 2. API key was revoked 3. Using API key instead of JWT token
Solutions:
# Check API key format (should be tm_xxx_ak_xxx)
echo $API_KEY | grep -E '^tm_.*_ak_.*$'
# Get a fresh JWT token
curl -X POST https://api.penfield.app/api/v2/auth/token \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json"
"Token expired" (401)¶
Symptom:
Solution:
# Refresh using refresh token
curl -X POST https://api.penfield.app/api/v2/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refresh_token": "YOUR_REFRESH_TOKEN"}'
Prevention:
- Store token expiry time: expires_at = time.time() + expires_in
- Refresh proactively when time.time() > expires_at - 300
"Insufficient permissions" (403)¶
Symptom:
{
"status": "error",
"error": {
"code": "AUTH_INSUFFICIENT_PERMISSIONS",
"message": "Insufficient permissions. Required scope(s): write"
}
}
Solution:
Request a new token with the required scopes:
- read - For reading/searching
- write - For creating/updating/deleting
- profile - For profile access
- offline_access - For refresh tokens
Check available scopes via discovery:
curl -s https://api.penfield.app/.well-known/oauth-authorization-server | \
python3 -c "import sys,json; print(json.load(sys.stdin)['scopes_supported'])"
Validation Errors¶
"Validation failed" (400)¶
Symptom:
{
"status": "error",
"error": {
"code": "VAL_VALIDATION_FAILED",
"message": "Validation failed",
"details": {
"field": "content",
"issue": "exceeds maximum length"
}
}
}
Common causes and limits:
| Field | Limit | Solution |
|---|---|---|
content |
10,000 chars | Truncate, split into multiple memories, upload as a document, or store as an artifact with a summary memory linking to it |
importance |
0.0-1.0 | Ensure value is in range |
tags |
10 max | Use fewer, broader tags |
memory_type |
11 valid types | Check Memory Types Guide |
"Invalid UUID format" (400)¶
Symptom:
Solution:
UUIDs must be in standard format: 550e8400-e29b-41d4-a716-446655440000
import uuid
# Validate before sending
try:
uuid.UUID(memory_id)
except ValueError:
raise ValueError(f"Invalid UUID: {memory_id}")
"Invalid relationship type" (400)¶
Solution: Use one of the 24 valid relationship types:
supersedes, updates, evolution_of, supports, contradicts,
disputes, parent_of, child_of, sibling_of, causes,
influenced_by, prerequisite_for, implements, documents,
example_of, tests, responds_to, references, inspired_by,
follows, precedes, depends_on, composed_of, part_of
Search Issues¶
No Results Returned¶
Possible causes:
- Query too specific
- Try broader search terms
-
Remove filters temporarily
-
Memories not indexed yet
- Wait a few seconds after creating
-
Embeddings are generated asynchronously
-
Wrong source_type filter
-
Date filter too narrow
Low Relevance Scores¶
Symptom: Results return but with low scores (< 0.1)
Solutions: 1. Include more keywords in your memories 2. Use more descriptive content 3. Check if your query matches the language in your memories
Results Not in Expected Order¶
The hybrid search combines: - BM25 (keyword matching) - Vector (semantic similarity) - Graph (relationship traversal)
If important results appear lower:
1. Increase their importance score
2. Add more relationships to them
3. Include relevant keywords in their content
Rate Limiting¶
"Rate limit exceeded" (429)¶
Symptom:
{
"status": "error",
"error": {
"code": "BIZ_RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded"
}
}
Response headers:
Solutions:
-
Wait and retry:
-
Implement exponential backoff:
-
Batch operations to reduce request count
-
Upgrade tier for higher limits
Connection/Network Issues¶
Timeouts¶
Symptom: Request hangs or times out
Solutions:
-
Set reasonable timeouts:
-
Use retry logic:
SSL Certificate Errors¶
Symptom: SSL: CERTIFICATE_VERIFY_FAILED
Solutions: 1. Update your CA certificates 2. Check system time is correct 3. Don't disable SSL verification in production
Memory/Relationship Issues¶
"Memory not found" (404)¶
Causes: 1. Memory was deleted 2. Wrong UUID 3. Memory belongs to different tenant
Solution:
# Verify memory exists
curl -X GET "https://api.penfield.app/api/v2/memories/$MEMORY_ID" \
-H "Authorization: Bearer $TOKEN"
"Relationship already exists" (409)¶
Cause: Trying to create a duplicate relationship
Solutions: 1. Check if relationship exists first 2. Use a different relationship type 3. Update existing relationship instead
Circular Relationship Warning¶
Creating A → B → C → A can cause infinite traversal loops.
Prevention:
- Design relationships as directed acyclic graphs when possible
- Set max_depth limits on traversal operations
Artifact Issues¶
"Invalid path" (400)¶
Path rules:
- Must start with /
- Must include filename (not just directory)
- No .. (path traversal)
- No hidden files starting with .
- Max depth: 10 levels
- Valid chars: alphanumeric, -, _, ., /
Examples:
"Artifact already exists" (409)¶
Solutions: 1. Use a different path 2. Delete existing artifact first 3. Update content instead of creating new
MCP Integration Issues¶
Tool Not Working¶
Checklist: 1. MCP server URL correct? 2. Authorization header set? 3. API key has required scopes? 4. Request body format correct?
Personality Not Loading (awaken)¶
Solution:
1. Check if personality is configured in Portal
2. Call awaken at conversation start
3. Or use restore_context("awakening")
Debugging Tips¶
Enable Request Logging¶
import logging
import requests
logging.basicConfig(level=logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
Check Request ID¶
Every response includes a request_id in the meta section:
Include this when contacting support.
Verify Token Contents¶
Check:
- exp - Expiration time
- scope - Granted scopes
- tenant_id - Correct tenant
Getting Help¶
If you're still stuck:
- Check the error code - See Error Handling Guide
- Review the API docs - Verify request format
- Check status page - For service issues
- Contact support - Include
request_idand error details