| name | maintainx-common-errors |
| description | Debug and resolve common MaintainX API errors.
Use when encountering API errors, authentication issues,
or unexpected responses from the MaintainX API.
Trigger with phrases like "maintainx error", "maintainx 401",
"maintainx api problem", "maintainx not working", "debug maintainx".
|
| allowed-tools | Read, Write, Edit, Bash(curl:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
MaintainX Common Errors
Overview
Quick reference guide for diagnosing and resolving common MaintainX API errors.
Prerequisites
- MaintainX API credentials configured
- Basic understanding of HTTP status codes
- Access to API logs
Error Reference
Authentication Errors (4xx)
401 Unauthorized
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}
Causes:
- Missing API key in request
- Invalid or expired API key
- Incorrect Authorization header format
Solutions:
const apiKey = process.env.MAINTAINX_API_KEY;
if (!apiKey) {
throw new Error('MAINTAINX_API_KEY environment variable not set');
}
const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
};
Quick Fix Script:
#!/bin/bash
if [ -z "$MAINTAINX_API_KEY" ]; then
echo "ERROR: MAINTAINX_API_KEY not set"
exit 1
fi
echo "Testing MaintainX authentication..."
RESPONSE=$(curl -s -w "\n%{http_code}" \
-H "Authorization: Bearer $MAINTAINX_API_KEY" \
-H "Content-Type: application/json" \
"https://api.getmaintainx.com/v1/users?limit=1")
HTTP_CODE=$(echo "$RESPONSE" | tail -n 1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" == "200" ]; then
echo "SUCCESS: Authentication working"
echo "$BODY" | jq '.users | length' | xargs -I {} echo "Found {} users"
else
echo "FAILED: HTTP $HTTP_CODE"
echo "$BODY"
fi
403 Forbidden
{
"error": "Forbidden",
"message": "Insufficient permissions for this operation"
}
Causes:
- API key doesn't have required permissions
- Plan tier doesn't include this feature
- Organization restrictions
Solutions:
const headers = {
'Authorization': `Bearer ${apiKey}`,
'X-Organization-Id': orgId,
'Content-Type': 'application/json',
};
Request Errors (4xx)
400 Bad Request
{
"error": "Bad Request",
"message": "Validation failed",
"details": {
"title": "Title is required"
}
}
Common Causes:
await client.createWorkOrder({
description: 'Some description',
});
await client.createWorkOrder({
title: 'Work Order Title',
description: 'Some description',
});
await client.createWorkOrder({
title: 'Test',
priority: 'URGENT',
});
await client.createWorkOrder({
title: 'Test',
priority: 'HIGH',
});
await client.createWorkOrder({
title: 'Test',
dueDate: '2025-01-15',
});
await client.createWorkOrder({
title: 'Test',
dueDate: new Date('2025-01-15').toISOString(),
});
404 Not Found
{
"error": "Not Found",
"message": "Work order not found"
}
Causes & Solutions:
const workOrder = await client.getWorkOrder('invalid_id');
async function safeGetWorkOrder(client, id) {
try {
return await client.getWorkOrder(id);
} catch (error) {
if (error.response?.status === 404) {
console.error(`Work order ${id} not found`);
return null;
}
throw error;
}
}
422 Unprocessable Entity
{
"error": "Unprocessable Entity",
"message": "Invalid data",
"details": {
"assetId": "Asset does not exist"
}
}
Solutions:
async function createWorkOrderSafe(client, data) {
if (data.assetId) {
try {
await client.getAsset(data.assetId);
} catch (e) {
throw new Error(`Asset ${data.assetId} not found`);
}
}
if (data.locationId) {
try {
await client.getLocation(data.locationId);
} catch (e) {
throw new Error(`Location ${data.locationId} not found`);
}
}
return client.createWorkOrder(data);
}
Rate Limiting (429)
{
"error": "Too Many Requests",
"message": "Rate limit exceeded",
"retryAfter": 60
}
Solution:
async function withRateLimitHandling(operation, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
if (error.response?.status === 429) {
const retryAfter = error.response.headers['retry-after'] || 60;
console.log(`Rate limited. Waiting ${retryAfter}s...`);
if (attempt < maxRetries) {
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
}
throw error;
}
}
}
Server Errors (5xx)
500 Internal Server Error
Solutions:
async function withRetry(operation, options = {}) {
const { maxRetries = 3, baseDelay = 1000 } = options;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
const status = error.response?.status;
if (status >= 500 && attempt < maxRetries) {
const delay = baseDelay * Math.pow(2, attempt);
console.log(`Server error. Retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
continue;
}
throw error;
}
}
}
503 Service Unavailable
Solutions:
- Check MaintainX status page
- Wait and retry
- Implement circuit breaker pattern
class CircuitBreaker {
private failures = 0;
private lastFailure?: Date;
private readonly threshold = 5;
private readonly resetTimeout = 60000;
async execute<T>(operation: () => Promise<T>): Promise<T> {
if (this.isOpen()) {
throw new Error('Circuit breaker is open - service unavailable');
}
try {
const result = await operation();
this.reset();
return result;
} catch (error) {
this.recordFailure();
throw error;
}
}
private isOpen(): boolean {
if (this.failures < this.threshold) return false;
if (!this.lastFailure) return ;
elapsed = .() - ..();
elapsed < .;
}
() {
.++;
. = ();
}
() {
. = ;
. = ;
}
}
Debugging Checklist
async function debugApiCall(client, operation, description) {
console.log(`\n=== ${description} ===`);
try {
const startTime = Date.now();
const result = await operation();
const duration = Date.now() - startTime;
console.log(`SUCCESS (${duration}ms)`);
console.log('Response:', JSON.stringify(result, null, 2).slice(0, 500));
return result;
} catch (error) {
console.log('FAILED');
console.log('Status:', error.response?.status);
console.log('Error:', error.response?.data || error.message);
console.(, error.?.);
error;
}
}
(
client,
client.({ : }),
);
Output
- Identified error cause
- Applied appropriate fix
- Verified resolution
Quick Reference
| Status | Cause | First Action |
|---|
| 401 | Auth issue | Check API key format |
| 403 | Permissions | Verify plan tier |
| 400 | Bad request | Check required fields |
| 404 | Not found | Verify resource ID |
| 422 | Invalid data | Validate references |
| 429 | Rate limit | Wait and retry |
| 5xx | Server error | Retry with backoff |
Resources
Next Steps
For comprehensive debugging, see maintainx-debug-bundle.