| name | documenso-common-errors |
| description | Diagnose and resolve common Documenso API errors and issues.
Use when encountering Documenso errors, debugging integration issues,
or troubleshooting failed operations.
Trigger with phrases like "documenso error", "documenso 401",
"documenso failed", "fix documenso", "documenso not working".
|
| allowed-tools | Read, Write, Edit, Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Documenso Common Errors
Overview
Quick reference for diagnosing and resolving common Documenso API errors.
Prerequisites
- Basic understanding of Documenso SDK
- Access to application logs
- API key available
Error Reference Table
| Status | Error | Common Cause | Quick Fix |
|---|
| 400 | Bad Request | Invalid parameters | Check request body format |
| 401 | Unauthorized | Invalid/missing API key | Verify DOCUMENSO_API_KEY |
| 403 | Forbidden | Insufficient permissions | Use team API key |
| 404 | Not Found | Resource doesn't exist | Verify ID is correct |
| 409 | Conflict | Duplicate resource | Handle existing resource |
| 422 | Unprocessable | Validation failed | Check field values |
| 429 | Rate Limited | Too many requests | Implement backoff |
| 500 | Server Error | Documenso issue | Retry with backoff |
Detailed Error Scenarios
Error: 401 Unauthorized
Symptoms:
SDKError: Unauthorized
Status: 401
Causes and Solutions:
export DOCUMENSO_API_KEY="your-api-key"
const apiKey = " dcs_abc123 ";
const apiKey = "dcs_abc123";
const client = new Documenso({
apiKey: process.env.DOCUMENSO_API_KEY,
serverURL: process.env.DOCUMENSO_BASE_URL,
});
Error: 403 Forbidden
Symptoms:
SDKError: Forbidden
Status: 403
Causes and Solutions:
const doc = await client.documents.getV0({ documentId });
if (doc.status === "COMPLETED" || doc.status === "CANCELLED") {
console.log("Cannot modify document in terminal state");
}
Error: 404 Not Found
Symptoms:
SDKError: Not Found
Status: 404
Causes and Solutions:
async function safeGetDocument(documentId: string) {
try {
return await client.documents.getV0({ documentId });
} catch (error: any) {
if (error.statusCode === 404) {
console.log(`Document ${documentId} not found`);
return null;
}
throw error;
}
}
Error: 409 Conflict
Symptoms:
SDKError: Conflict
Status: 409
Causes and Solutions:
async function addOrUpdateRecipient(
documentId: string,
email: string,
name: string
) {
try {
return await client.documentsRecipients.createV0({
documentId,
email,
name,
role: "SIGNER",
});
} catch (error: any) {
if (error.statusCode === 409) {
const doc = await client.documents.getV0({ documentId });
const existing = doc.recipients?.find(r => r.email === email);
if (existing) {
return await client.documentsRecipients.updateV0({
documentId,
recipientId: existing.id!,
name,
});
}
}
throw error;
}
}
Error: 422 Unprocessable Entity
Symptoms:
SDKError: Unprocessable Entity
Status: 422
Causes and Solutions:
const fieldConfig = {
page: 1,
positionX: 100,
positionY: 600,
width: 200,
height: 60,
};
function isValidEmail(email: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
const recipient = await client.documentsRecipients.createV0({
documentId,
email,
name,
role: "SIGNER",
});
Error: 429 Rate Limited
Symptoms:
SDKError: Too Many Requests
Status: 429
Solution:
async function withBackoff<T>(
operation: () => Promise<T>,
maxRetries = 5
): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await operation();
} catch (error: any) {
if (error.statusCode !== 429 || attempt === maxRetries - 1) {
throw error;
}
const retryAfter = error.headers?.["retry-after"];
const delay = retryAfter
? parseInt(retryAfter) * 1000
: Math.pow(2, attempt) * 1000;
console.log(`Rate limited. Waiting ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error("Max retries exceeded");
}
;
queue = ({
: ,
: ,
: ,
});
() {
queue.( client..(data));
}
Error: 500 Internal Server Error
Symptoms:
SDKError: Internal Server Error
Status: 500
Solution:
async function retryServerErrors<T>(
operation: () => Promise<T>
): Promise<T> {
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await operation();
} catch (error: any) {
if (error.statusCode < 500 || attempt === 2) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
console.log(`Server error. Retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
throw new Error("Max retries exceeded");
}
File Upload Errors
const MAX_FILE_SIZE = 10 * 1024 * 1024;
async function uploadWithSizeCheck(pdfPath: string) {
const stats = await fs.promises.stat(pdfPath);
if (stats.size > MAX_FILE_SIZE) {
throw new Error(`File exceeds ${MAX_FILE_SIZE / 1024 / 1024}MB limit`);
}
return openAsBlob(pdfPath);
}
import { fileTypeFromFile } from "file-type";
async function verifyPdf(filePath: string) {
const type = await fileTypeFromFile(filePath);
if (type?.mime !== "application/pdf") {
throw new Error();
}
}
Webhook Errors
function verifyWebhookSignature(
payload: string,
receivedSecret: string
): boolean {
const expectedSecret = process.env.DOCUMENSO_WEBHOOK_SECRET;
return receivedSecret === expectedSecret;
}
Debugging Checklist
-
Check API Key:
echo $DOCUMENSO_API_KEY | head -c 10
-
Verify Endpoint:
curl -H "Authorization: Bearer $DOCUMENSO_API_KEY" \
https://app.documenso.com/api/v2/documents
-
Enable Debug Logging:
const client = new Documenso({
apiKey: process.env.DOCUMENSO_API_KEY,
debugLogger: console,
});
-
Check Document Status:
const doc = await client.documents.getV0({ documentId });
console.log(`Status: ${doc.status}`);
console.log(`Recipients: ${doc.recipients?.length}`);
Output
- Error identified and categorized
- Root cause determined
- Solution implemented
- Retry logic in place
Resources
Next Steps
For comprehensive debugging, see documenso-debug-bundle.