API & SDK Errors
Pulsabase errors follow a consistent structure across the SDK and HTTP API. All errors include a machine-readable code, a human-readable message, and optionally a request_id for debugging.
Pulsabase standardizes errors across both its backend engine and frontend SDKs. Understanding how errors are structured will help you handle constraint violations, validation failures, and permission denials effectively.
SDK Exceptions
Section titled “SDK Exceptions”The Pulsabase SDK throws two specific types of errors which you can catch and handle:
PulsabaseValidationError: Thrown before a request is sent to the network. It occurs when client-side schema validation (Pulse.rulesdefined via decorators) fails.PulsabaseApiError: Thrown when the backend API returns an error response.
import { PulsabaseValidationError, PulsabaseApiError } from 'pulsabase';
try { await pb.from(User).insert({ email: 'bad-email' });} catch (err) { if (err instanceof PulsabaseValidationError) { console.error('Validation failed on fields:', err.errors); // e.g. [{ field: 'email', message: 'must be a valid email' }] } else if (err instanceof PulsabaseApiError) { if (err.isUniqueViolation()) { console.error('This email is already taken!'); } console.error(`API Error [${err.code}]:`, err.message); }}import 'package:pulsabase/pulsabase.dart';
try { await pb.from('users').insert({'email': 'bad-email'});} catch (e) { if (e is PulsabaseValidationError) { print('Validation failed: ${e.errors}'); } else if (e is PulsabaseApiError) { if (e.isUniqueViolation()) { print('This email is already taken!'); } print('API Error [${e.code}]: ${e.message}'); }}API Error Response Format
Section titled “API Error Response Format”If you are interacting with Pulsabase directly via cURL or REST, a failed API request will return a standard JSON object.
Standard Response (Production)
Section titled “Standard Response (Production)”{ "code": "CONSTRAINT_UNIQUE", "message": "A record with this value already exists (unique constraint violation).", "request_id": "550e8400-e29b-41d4-a716-446655440000"}Debug Mode Enabled
Section titled “Debug Mode Enabled”If your project has Debug Mode enabled via the Pulsabase Dashboard Settings, the core engine securely injects a comprehensive debug object into the payload to help you troubleshoot data and schema issues faster. You do not need to send any special headers or flags from your frontend SDK; it is handled automatically based on your project’s environment.
{ "code": "CONSTRAINT_UNIQUE", "message": "A record with this value already exists (unique constraint violation).", "request_id": "550e8400-e29b-41d4-a716-446655440000", "debug": { "field": "email", "pg_error": "duplicate key value violates unique constraint \"users_email_key\"", "suggestion": "Check if the payload contains a duplicate value for this unique column." }}Security Note: To securely prevent SQL architecture and internal database structure leaks, the
debugpayload is completely stripped out of API responses when running in production mode. Additionally, thepg_errorstring only forwards safe Postgres constraint error descriptions—it never exposes the raw generated SQL query that was executed.
Engine Error Codes
Section titled “Engine Error Codes”All possible code values returned by the Pulsabase core engine:
Constraint & Data Integrity
Section titled “Constraint & Data Integrity”| Code | HTTP Status | Description |
|---|---|---|
CONSTRAINT_UNIQUE | 409 | A unique constraint was violated (e.g., duplicate email) |
CONSTRAINT_FOREIGN_KEY | 409 | A foreign key constraint was violated (referenced record doesn’t exist) |
CONSTRAINT_NOT_NULL | 400 | A required field is missing |
CONSTRAINT_CHECK | 400 | A check constraint (e.g., score > 0) was violated |
Authentication & Permissions
Section titled “Authentication & Permissions”| Code | HTTP Status | Description |
|---|---|---|
PERMISSION_DENIED | 403 | Insufficient privileges to perform this operation (RLS blocks this) |
RLS_VIOLATION | 403 | Row-Level Security explicitly denied the query operation |
Query & Execution Errors
Section titled “Query & Execution Errors”| Code | HTTP Status | Description |
|---|---|---|
INVALID_QUERY | 400 | The query JSON structure is malformed |
INVALID_OPERATOR | 400 | An invalid logical or comparison operator was used |
INJECTION_BLOCKED | 400 | Potential SQL injection payload was detected and blocked |
QUERY_TIMEOUT | 408 | The database query exceeded its maximum allowed execution time |
Schema Routing Errors
Section titled “Schema Routing Errors”| Code | HTTP Status | Description |
|---|---|---|
INVALID_TABLE | 400 | The specified table does not exist or is not exposed |
INVALID_COLUMN | 400 | One or more requested columns do not exist |
TABLE_NOT_FOUND | 404 | The specified table was directly not found |
COLUMN_NOT_FOUND | 404 | The specified column was directly not found |
RELATION_ERROR | 500 | An error occurred while resolving a relational query path |
Internal Errors
Section titled “Internal Errors”| Code | HTTP Status | Description |
|---|---|---|
INTERNAL_ERROR | 500 | An unexpected database or server error occurred |
SDK Local Errors
Section titled “SDK Local Errors”The SDK may generate these codes internally before hitting the network, or wrap specific network failures into them:
| Code | Description |
|---|---|
INVALID_PAYLOAD | The mutation payload (for insert, update, upsert) is invalid. |
INVALID_ACTION | You provided an unsupported or unknown query action type. |
RATE_LIMIT | Hard-coded API rate limit exceeded by the client. |
CONNECTION_ERROR | The API is unreachable, or the websocket disconnected abruptly. |
EXECUTION_ERROR | SDK-level failure during query execution and state parsing. |