Error Messages Quality
Real error messages from real services. Some help you fix the problem in seconds. Others make you question your career.
{
"error": {
"code": "card_declined",
"decline_code": "insufficient_funds",
"doc_url": "https://stripe.com/docs/error-codes/card-declined",
"message": "Your card has insufficient funds.",
"param": "source",
"type": "card_error"
}
}{
"error": {
"code": "resource_missing",
"message": "No such customer: 'cus_nonexistent'",
"param": "customer",
"type": "invalid_request_error"
}
}Every error includes code, message, param, type, and doc_url. Machine-readable and human-readable at the same time.
Webhook signature errors could be more specific about what went wrong with the signature.
The gold standard. Every error has a dedicated docs page. SDKs throw typed exceptions.
ClerkRuntimeError: Clerk: auth() was called but Clerk can't detect usage of clerkMiddleware(). Please ensure the following: 1. clerkMiddleware() is used in your middleware.ts 2. Your middleware.ts is located at the root of your app
Clerk: You need to add your Publishable Key to the <ClerkProvider publishableKey={YOUR_KEY} />Framework-specific errors that mention the exact file and component you need to change.
JWT validation errors are generic — 'Invalid token' without specifying which claim failed.
Great DX. Errors read like mini-tutorials. Framework integration errors are especially good.
{
"type": "error",
"error": {
"type": "rate_limit_error",
"message": "Number of request tokens has exceeded your daily rate limit (80000) of tokens per minute. Please reduce your request rate."
}
}{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "messages: roles must alternate between \"user\" and \"assistant\", but found two consecutive \"user\" roles"
}
}Error types are enum-like and stable: rate_limit_error, invalid_request_error, api_error — easy to handle in code.
Streaming errors can arrive mid-stream as an error event, which requires careful client-side handling that the docs could better highlight.
Follows the OpenAI error pattern but improves on it. Rate limit messages include actual numbers. Message validation errors are specific.
{
"errors": [
{
"message": "Variable \"$input\" of type \"IssueCreateInput!\" has invalid value: Field \"title\" of required type \"String!\" was not provided.",
"extensions": { "code": "VALIDATION_ERROR" }
}
]
}{
"errors": [
{
"message": "Rate limit exceeded. Retry after 1.2 seconds.",
"extensions": { "code": "RATE_LIMITED", "retryAfter": 1.2 }
}
]
}GraphQL errors with extensions.code make programmatic handling easy. Validation errors reference exact field paths.
Webhook delivery failures in dashboard lack detail about why the endpoint rejected the payload.
Among the best GraphQL API error implementations. Consistent structure, machine-readable codes, and clear messages.
{
"statusCode": 422,
"message": "The 'to' field must contain a valid email address.",
"name": "validation_error"
}{
"statusCode": 403,
"message": "You can only send emails to your own email address until you verify a domain.",
"name": "validation_error"
}Errors are aware of your account state — sandbox restrictions explained clearly with the path to lift them.
Rate limit errors don't include retry-after timing or current usage numbers.
Tiny API surface means few error types, but each one is crafted well. Onboarding-state-aware errors are a standout feature.
ConvexError: Server function "api.users.create" failed:
Argument validation failed:
Field "email": Expected string, received undefined
at convex/users.ts:15ConvexError: Query function "api.users.list" returned more than 8MB of data. Hint: Add .paginate() to return results in smaller chunks.
Server function errors include full file paths, argument validation details, and actionable hints for platform limits.
WebSocket reconnection errors during development can produce noisy console output before auto-recovering.
Excellent DX. Errors reference your code, not internal stack frames. Platform limit errors always suggest the workaround.
CypressError: `cy.get()` timed out retrying after 4000ms Expected to find element: `[data-testid="submit-btn"]`, but never found it. Learn more: https://on.cypress.io/element-not-found
CypressError: `cy.request()` failed on: http://localhost:3000/api/users The response we received from your web server was: 404 Not Found This was considered a failure because the status code was not 2xx or 3xx.
Every error includes the command that failed, what was expected, what actually happened, and a doc link.
Flaky test detection messages could better explain WHY a test is flaky rather than just flagging it.
Best-in-class test runner errors. The visual Test Runner plus detailed error messages make debugging tests genuinely pleasant.
Error: expect(locator).toBeVisible
Locator: getByRole('button', { name: 'Submit' })
Expected: visible
Received: <element is not attached to the DOM>
Call log:
- waiting for getByRole('button', { name: 'Submit' })
- locator resolved to 0 elementsError: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:3000 =========================== logs =========================== navigating to "http://localhost:3000", waiting until "load"
Call logs showing each step Playwright took before failure. Locator resolution details eliminate selector guessing.
Trace viewer errors are excellent but require opening a separate HTML report — not inline in terminal.
Rivals Cypress for test error quality. Call logs are a standout feature — you see exactly what the framework tried. Trace viewer is the ultimate debugging tool.
FAIL tests/utils.test.ts > formatDate > should format ISO date AssertionError: expected 'Mar 15, 2024' to be 'March 15, 2024' - Expected + Received - March 15, 2024 + Mar 15, 2024 ❯ tests/utils.test.ts:15:22
TypeError: Cannot read properties of undefined (reading 'map') ❯ src/utils.ts:42:15 ❯ tests/utils.test.ts:8:18
Diff-style assertion output with color coding. Test hierarchy in failure output helps locate the exact test.
Module resolution errors for ESM/CJS mismatches produce Node-level errors that Vitest doesn't interpret.
Inherits the best of Jest's error formatting with better ESM support. Fast feedback loop makes error messages feel less painful.
✗ High severity vulnerability found in lodash
Description: Prototype Pollution
Info: https://snyk.io/vuln/SNYK-JS-LODASH-1040724
Introduced through: my-app@1.0.0 > express@4.18.2 > lodash@4.17.20
Fix: Upgrade lodash to 4.17.21
npm install lodash@4.17.21✗ License issue: GPL-3.0 license detected in package "some-lib@2.0.0" Introduced through: my-app > other-pkg > some-lib
Dependency chain tracing from your package.json to the vulnerable transitive dep, with exact fix commands.
False positives for vulnerabilities in dev dependencies that never ship to production lack context about actual risk.
Best vulnerability reporting in the ecosystem. Dependency chain visibility and one-command fixes make security scanning actually usable.
lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Unexpected any. Specify a different type.
> 5 │ function foo(x: any) {
│ ^^^
i Disabling any disables many important type checks. Consider using unknown instead.error[migrate]: Configuration file not compatible with Biome 2.x biome.json:3:5 'formatter.indentSize' is deprecated. Use 'formatter.indentWidth' instead.
Visual column pointers (^^^) under the offending code make it instantly clear what triggered the rule.
Import organization errors can produce many violations at once with little grouping — wall of red.
Borrowed Rust compiler error style. High signal, low noise. Most errors include a suggested fix or alternative.
ZodError: [
{
"code": "invalid_type",
"expected": "string",
"received": "number",
"path": ["user", "email"],
"message": "Expected string, received number"
}
]ZodError: [
{ "code": "too_small", "minimum": 8, "type": "string", "inclusive": true, "message": "String must contain at least 8 character(s)", "path": ["password"] }
]Structured ZodError with path arrays makes errors trivially mappable to form field names.
Union type errors (z.union) produce verbose output listing every branch that failed — hard to read with large schemas.
Best-in-class validation errors. The path array is a killer feature — frontend form libraries use it directly to highlight the right field.
AstroError: Could not find Sharp. Please install it manually into your project: npm install sharp Learn more: https://docs.astro.build/en/guides/images/#sharp
AstroError: Failed to load Vite config
src/pages/index.astro: Expected closing tag for <div> (line 18)
> 18 | <div class="foo"
| ^Missing dependency errors always include the exact install command — zero googling needed.
Hydration errors with multiple islands can be confusing — error may surface at the wrong component.
One of the better build-tool error experiences. Clear hierarchy: build errors, server errors, and hydration errors are visually distinct.
InngestFunctionError: Function "user/send-welcome" failed after 3 retries. Last error: Error: SMTP connection refused at smtp.example.com:587 Step: "send-email" (step 2 of 3) Retry history: attempt 1 (2m ago), attempt 2 (10m ago), attempt 3 (30m ago)
InngestDevServerError: No serve handler found at POST /api/inngest. Make sure you've added the serve() handler in your app.
Step-level error attribution with retry history. Errors in distributed step functions are usually impossible to trace — Inngest solves this.
Event schema validation errors could be more specific about which field failed.
Excellent for background jobs. The retry history in errors is a standout feature — you can see the degradation pattern, not just the final failure.
error: Uncaught (in promise) PermissionDenied: Requires read access to "/etc/passwd", run again with the --allow-read flag
at async Deno.readTextFile (ext:deno_fs/30_fs.js:742:10)error: Module not found "npm:express@4.18.2". If you're using an npm package, make sure you have an import map or deno.json configured.
Permission errors always include the exact --allow-X flag and the resource path. Deno's security model could be confusing — these errors make it learnable.
TypeScript type errors from Deno's built-in checker can be verbose and hard to distinguish from your own code's type errors.
Permission-related errors are best-in-class. The model of 'error says exactly what to allow' is perfect for a sandboxed runtime.
Error: Cannot import $lib/server/db in client-side code The module at "$lib/server/db" is only available on the server. This was imported from "src/routes/+page.svelte".
SvelteKitError: 'load' function in 'src/routes/blog/+page.ts' must return a plain object. Got: undefined
Server/client boundary errors name the offending import and trace its origin file — a lesson in how to write framework errors.
Hydration mismatch errors are less specific than they could be about which component caused the mismatch.
Among the best DX in modern meta-frameworks. Errors are written for developers, not stack traces.
APIError: INVALID_EMAIL_OR_PASSWORD status: 401 message: Invalid email or password
BetterAuthError: secret is required. Please set the secret in the auth config or BETTER_AUTH_SECRET environment variable.
Server-side errors are typed APIError instances; client mirrors the same shape via SDK.
Plugin compatibility errors can be terse when two plugins disagree on hooks.
Shape-consistent across server and client. Plugin system extends error codes coherently.
WorkOSError: organization_id is required code: 'invalid_request' status: 422 requestId: 'req_xxx'
{
"code": "sso_session_expired",
"message": "The SSO session has expired. Please re-authenticate.",
"status": 401
}Every error includes code, message, status, and request ID. SDK throws typed errors per category.
IdP-specific connection errors can echo upstream provider language verbatim.
Stripe-quality error design for enterprise auth. Consistent across SSO, Directory Sync, and AuthKit.
[plugin:vite:import-analysis] Failed to resolve import "./missing.ts" from "src/main.ts". Does the file exist? File: /Users/me/app/src/main.ts:3:18
[vite] Internal server error: Pre-transform error: Failed to load url /node_modules/.vite/deps/react.js Did you forget to install it?
In-browser error overlay shows source location and suggested fixes for HMR errors.
Some plugin errors lose attribution and show as 'internal server error' without context.
One of the best DX stories in modern build tools. The HMR overlay is a developer love letter.
BadRequestError: 400 {"error":{"message":"This model's maximum context length is 8192 tokens. However, your messages resulted in 8500 tokens.","type":"invalid_request_error","code":"context_length_exceeded"}}RateLimitError: 429 Rate limit reached for gpt-4 in organization org_xxx on requests per min. Limit: 200/min. Please try again in 200ms.
Typed exception classes per error type. Every error includes message, type, and code.
Tool-call validation errors could be more specific about which argument failed schema.
The pattern many AI SDKs now copy. Streaming errors handled gracefully via async iteration.
MuxError: 422 {"error":{"type":"invalid_parameters","messages":["input.url is invalid"]}, "request_id": "req_xxx"}{"error":{"type":"playback_id_not_found","messages":["No playback ID matched the provided value"]}}Stripe-inspired error envelope with type, messages, and request_id on every response.
Webhook signature validation errors could mention timestamp tolerance settings.
Video API errors are inherently tricky; Mux makes them debuggable.
Error: No QueryClient set, use QueryClientProvider to set one
Error: Missing queryFn for queryKey ["users", 1] If you don't want to use a queryFn at this point, please pass enabled: false
Errors describe what is missing and offer the canonical fix in the same sentence.
Suspense + Query errors can require reading both libraries' docs.
v5 cleaned up many warnings. Devtools panel surfaces query errors clearly.
BadRequestError: 400 {"type":"error","error":{"type":"invalid_request_error","message":"messages: at least one message is required"}}RateLimitError: 429 {"type":"error","error":{"type":"rate_limit_error","message":"Number of request tokens has exceeded your per-minute rate limit"}}Each error has type, message, and HTTP status. SDK exception classes per error type.
Tool-use validation errors could be more specific about which input field failed schema.
Mirrors OpenAI patterns with similar quality. Streaming errors are handled gracefully via the SDK.
BadRequestError: 400 {"error":{"message":"The model 'llama-3-9999b' does not exist","type":"invalid_request_error","code":"model_not_found"}}RateLimitError: 429 Rate limit reached for model llama-3.3-70b in organization org_xxx on tokens per minute (TPM): Limit 6000, Used 5800, Requested 500.
Rate limit errors include limit/used/requested values for accurate backoff.
Some streaming connection errors can be terse when the upstream model fails mid-response.
OpenAI-format errors mean existing handling code works without changes.
{
"type": "PolarRequestValidationError",
"detail": [
{
"loc": ["body", "amount"],
"msg": "Input should be greater than 0",
"type": "greater_than"
}
]
}{
"type": "ResourceNotFound",
"detail": "Product not found"
}Auto-generated SDK throws typed errors per schema. Validation errors include field paths.
Webhook signature errors could be more specific about timestamp vs hash mismatch.
Built on FastAPI so error format is consistent and well-structured.
KnockError: 422 {"code":"workflow_not_found","message":"Workflow with key 'welcome-email' not found in environment 'production'"}{"code":"invalid_recipient","message":"Recipient must include either user_id or object_id","status":422}Errors educate the developer about valid recipients and channel configurations.
Channel-specific delivery errors (e.g. SES rejection) inherit upstream provider messages verbatim.
Notification-platform errors are inherently complex; Knock surfaces them well.
StytchError: 401 {"status_code":401,"request_id":"request-id-test-xxx","error_type":"unauthorized_credentials","error_message":"The credentials provided are invalid"}{"error_type":"otp_code_not_found","error_message":"The provided OTP could not be found, or has expired"}Every error includes error_type, error_message, status_code, and request_id.
Some compound error types collapse multiple failure modes into one code.
Solid auth API errors. Documentation maps every error_type to recommended remediation.
{"ErrorCode": 406, "Message": "You tried to send to recipient(s) that have been marked as inactive."}{"ErrorCode": 300, "Message": "Invalid 'From' address: noreply@unverified.com is not a verified Sender Signature"}Numeric ErrorCode values are stable and indexed in docs. Each has a dedicated explanation.
Bulk send errors aggregate per-message failures into one response, requiring extra parsing.
One of the most thoughtful error catalogs in the email space. Errors map 1:1 to docs pages.
WorkOSError: invalid_authorization_code message: 'The authorization code has expired or has already been used' status: 422
{
"code": "directory_not_found",
"message": "Directory dir_xxx does not exist or you do not have access",
"status": 404
}Distinct codes for OAuth vs Directory vs Organization errors.
JWT validation errors don't always specify which claim failed.
AuthKit's error layer translates upstream IdP errors into WorkOS taxonomy.
DubApiError: 422 {"error":{"code":"unprocessable_entity","message":"Validation failed","doc_url":"https://dub.co/docs/api-reference/errors#unprocessable-entity"}}{"error":{"code":"conflict","message":"Link with key 'launch' already exists in this domain","doc_url":"https://dub.co/docs/api-reference/errors#conflict"}}Stripe-style errors with code, message, and doc_url on every response.
Bulk operations could include per-item error indexes.
OpenAPI-generated SDK gives consistent error class hierarchy across languages.
BetterAuthError: Database adapter "drizzle" requires the "drizzle-orm" package. Install it with: npm install drizzle-orm
BetterAuthError: OAuth provider "github" requires clientId and clientSecret. Set GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET environment variables.
Errors name the specific config field or dependency that's missing and suggest the fix.
Session validation errors are sometimes generic — 'Invalid session' without specifying why.
Great DX for setup errors. Runtime auth errors are clear. Plugin errors include the plugin name in context.
ConvexError: [QUERY] messages:list
Argument validation failed:
Expected { channelId: v.id("channels") } but got { channelId: undefined }Server Error: Document with ID "messages:abc123" not found in table "messages"
Function name, argument schema, and actual value shown together. Dashboard links to the exact function.
Internal Convex platform errors are opaque — 'Internal Server Error' without details.
Dashboard shows errors in real-time with stack traces. Validator errors are excellent. Platform errors (rare) are less helpful.
{
"error": {
"code": 429,
"message": "Rate limit exceeded for model anthropic/claude-3.5-sonnet. Retry after 2.3s.",
"metadata": { "provider": "anthropic", "model": "claude-3.5-sonnet", "retry_after": 2.3 }
}
}{
"error": {
"code": 402,
"message": "Insufficient credits. Add credits at https://openrouter.ai/credits"
}
}Errors include provider, model, and metadata. Rate limits have retry_after field.
Some upstream provider errors pass through without OpenRouter context.
Excellent error design. Provider fallback errors explain which providers were tried and why each failed.
TriggerError: Task "send-email" failed at step "validate-recipient" Attempt 2/3 | Next retry in 30s Error: Invalid email format: "not-an-email"
TriggerDevError: Cannot find task "process-order" in your project. Available tasks: send-email, sync-data, generate-report
Task errors include task name, step name, attempt number, and retry schedule.
Build errors during deployment sometimes show raw esbuild output.
Dashboard shows full error timeline per run. Step-level errors are excellent. Dev server errors are actionable.
InngestError: Function "user/signup.welcome-email" failed at step "send-email" NonRetriableError: Resend API key is invalid This step will NOT be retried.
InngestError: Event "user.signup" does not match any registered function. Registered events: user.created, order.placed, invoice.paid
Errors distinguish retriable vs non-retriable, include function/step context, and list available options.
Dev server startup errors with wrong serve handler can be confusing.
Dev server shows errors in real-time with replay. Production errors are just as detailed. Event-driven errors list available events.
Error: useState only works in Client Components. Add the "use client" directive at the top of the file to use it.
Error: Unsupported Server Component type: undefined. This might happen if you meant to export a component but accidentally exported a constant or undefined value.
Dev overlay with source-mapped stack traces and quick-fix suggestions for common mistakes.
React Server Component errors can be cryptic. 'Cannot access X on the server' without explaining which import chain caused it.
Dev mode errors are great. Production errors are stripped. RSC boundary errors are still confusing for newcomers.
Error: GROQ query parse error:
*[_type == "post" && {]
^
Expected expression but found "{"Schema error in document type "post":
Field "author" references type "reference" but "to" is not defined.
Did you mean: { type: 'reference', to: [{ type: 'author' }] }GROQ parse errors with caret positioning and schema errors with suggested fixes are genuinely excellent.
Real-time listener disconnection errors are vague — 'connection lost' without retry guidance.
Studio errors are some of the best in the CMS space. GROQ query errors rival Prisma for clarity. API errors are more standard.
/src/App.tsx 15:7 error 'useState' is defined but never used no-unused-vars 22:3 warning Unexpected console statement no-console ✖ 2 problems (1 error, 1 warning)
ESLint couldn't find the plugin "@typescript-eslint/eslint-plugin". (The package "@typescript-eslint/eslint-plugin" was not found when loaded as a Node module from the directory "/app".)
Rule name in every violation enables quick lookup, targeted disable, and config adjustment. Line:column precision.
Flat config migration errors (v8 → v9) can be confusing when mixing old and new config formats.
The standard for linter error formatting. Rule names as error codes is a pattern every tool should copy. Auto-fix for many rules is a bonus.
error: Cannot find module './utils' from 'src/index.ts'
at require ('bun:wrap')
at /home/user/project/src/index.ts:3:18BuildMessage {
message: "Unexpected ">"
level: "error"
position: { line: 12, column: 8 }
}Runtime errors match Node.js conventions — familiar to anyone who has used Node.
Bundler errors expose internal data structures instead of human-readable messages.
Good for runtime errors, rough edges on build/bundler errors. Improving with each release.
PrismaClientKnownRequestError: Invalid `prisma.user.findUnique()` invocation: An operation failed because it depends on one or more records that were required but not found. Record to update not found.
PrismaClientInitializationError: Can't reach database server at 'localhost:5432' Please make sure your database server is running at 'localhost:5432'.
Error P codes (P2002 for unique constraint etc.) let you programmatically handle specific database errors.
Schema migration errors can be cryptic when there are circular relations or complex composite types.
Good overall. P-error codes are useful for error handling in application code. Migration errors are the weak spot.
TriggerError: Task "process-invoice" failed in run rn_abc123. Error: Cannot read properties of null (reading 'amount') at processInvoice (src/trigger/invoice.ts:34:18) Run link: https://cloud.trigger.dev/runs/rn_abc123
TriggerError: API version mismatch. Your SDK is v3.0.1 but the server expects v3.1.x. Run: npm install @trigger.dev/sdk@latest
Run links in errors let you jump directly to the run's full logs, timing breakdown, and retry history.
Concurrency limit errors could include current queue depth to help you tune the limits.
Strong DX focus is visible in error design. Run links make the gap between error and debugging near zero.
VALIDATION_ERROR: Expected string at 'body.name' but got undefined
{
"type": "validation",
"on": "body",
"property": "name",
"expected": "string"
}TypeError: Cannot read properties of undefined (reading 'derive')
Validation errors are structured JSON with exact field path and expected type.
Plugin lifecycle errors are raw TypeErrors without framework context.
Validation DX is excellent thanks to TypeBox integration. Framework internals could use better error boundaries.
TRPCClientError:
[BAD_REQUEST] Input validation failed
path: user.create
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": ["email"]
}TRPCClientError: [UNAUTHORIZED] You must be logged in to perform this action
Zod validation errors flow through with full field paths and type expectations.
Custom procedure errors depend on what the developer throws — tRPC doesn't enforce quality.
Error quality depends heavily on Zod schemas. Framework errors (BAD_REQUEST, UNAUTHORIZED) are consistent. Custom errors vary.
[mintlify] Error in mint.json: "navigation" group "API Reference" references page "api/users" which does not exist. Available pages in api/: api/auth, api/projects, api/billing
[mintlify] MDX compilation error in docs/quickstart.mdx:15 Unknown component <Callout>. Did you mean <Note>?
Build errors reference the exact file, line, and suggest alternatives.
Some OpenAPI parsing errors show raw YAML parse failures without pointing to the issue.
Dev server errors are excellent — they point to the exact config or MDX issue. Deployment errors are less detailed.
{
"error": {
"code": "domain_not_found",
"message": "Domain 'example.com' is not configured. Add it in your Dub dashboard.",
"doc_url": "https://dub.co/docs/api-reference/domains"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Retry after 1s.",
"retry_after": 1
}
}Errors include error codes, doc URLs, and actionable messages.
Some bulk operation errors don't specify which item in the batch failed.
Follows Stripe-like error patterns. Well-designed API errors with consistent format.
Error: The Serverless Function "api/hello" is 58mb which exceeds the maximum size limit of 50mb.
Error: FUNCTION_INVOCATION_TIMEOUT Task timed out after 10.00 seconds
Build errors with specific file paths and size limits are genuinely helpful.
Runtime errors in production logs are stripped of context. FUNCTION_INVOCATION_TIMEOUT tells you nothing.
Build errors are decent. Runtime/deployment errors can be maddeningly vague. Edge runtime errors are worse.
{
"code": "PGRST301",
"details": null,
"hint": null,
"message": "JWSError JWSInvalidSignature"
}{
"code": "23505",
"details": "Key (email)=(test@test.com) already exists.",
"hint": null,
"message": "duplicate key value violates unique constraint \"users_email_key\""
}Auth errors from GoTrue are clear and well-structured with proper HTTP codes.
Raw Postgres error codes (23505, 42501) leak through PostgREST with no translation layer.
Two layers of errors: GoTrue auth (good) and PostgREST/Postgres (raw). RLS errors are especially cryptic.
{
"message": "Invalid Application-ID or API key",
"status": 403
}{
"message": "indexName is not valid. Expected a non-empty string.",
"status": 400
}Consistent JSON format with clear parameter validation messages.
Rate limiting errors don't tell you your current usage or when to retry.
Consistent and readable. Not spectacular but never terrible. Missing error codes and retry-after headers.
{
"code": 21211,
"message": "The 'To' number +1555INVALID is not a valid phone number.",
"more_info": "https://www.twilio.com/docs/errors/21211",
"status": 400
}{
"code": 20003,
"message": "Authentication Error - No credentials provided",
"more_info": "https://www.twilio.com/docs/errors/20003",
"status": 401
}Every error has a numeric code and a link to a dedicated docs page with troubleshooting steps.
Error messages are short and sometimes cryptic — the real help is always behind the docs link.
Twilio's error directory is great but you're always one click away from understanding. Messages alone are often not enough.
NeonDbError: connection is insecure (try using `sslmode=require`) at /app/node_modules/@neondatabase/serverless/index.js
NeonDbError: endpoint is disabled Hint: The compute endpoint has been suspended due to inactivity. It should resume automatically.
Postgres errors come through with the original detail intact plus Neon-specific hints for cloud-specific issues.
WebSocket connection errors during cold starts show raw protocol messages that look alarming but are usually transient.
Above-average for a database SDK. Neon-specific errors have actionable hints. Raw Postgres errors still require lookup.
HTTPException: Unauthorized status: 401 message: "Unauthorized"
ZodError: [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": ["body", "email"],
"message": "Required"
}
]Zod validator integration gives detailed, path-aware validation errors that bubble up cleanly to the response.
HTTPException is a blank slate — framework throws it correctly but messages are whatever the developer set (often nothing).
Framework-level error quality depends heavily on middleware used. Zod integration is excellent; bare HTTPException is thin.
DrizzleError: Column "userId" does not exist Hint: Available columns: id, email, name, createdAt
PostgresError: relation "users" does not exist code: '42P01'
Schema introspection errors (wrong column, wrong table) leverage Drizzle's compile-time type info to list valid alternatives.
Postgres driver errors pass through with raw codes. Migration-related errors get no Drizzle-layer interpretation.
Better than most ORMs for schema-related errors. Driver errors still require knowing Postgres error codes. No doc links in errors.
SentryCliError: Authentication credentials were not provided. Use `sentry-cli login` or set SENTRY_AUTH_TOKEN environment variable.
Error: Could not determine release name. Please pass --release or set SENTRY_RELEASE.
CLI errors consistently suggest the fix — either a flag or an environment variable.
SDK initialization errors in the browser are swallowed silently. DSN typos produce no visible error.
CLI errors are excellent. SDK errors are intentionally silent (monitoring shouldn't break your app). API errors are standard REST.
{
"sys": { "type": "Error", "id": "NotFound" },
"message": "The resource could not be found.",
"details": { "type": "Entry", "id": "abc123", "space": "my-space" }
}{
"sys": { "type": "Error", "id": "VersionMismatch" },
"message": "Version mismatch error. The version you specified was incorrect. This may be due to someone else editing the content."
}Resource errors include sys.id as machine-readable error type plus the affected entity details.
Version mismatch errors don't include the current version, forcing an extra API call every time.
Consistent JSON structure across the API. Resource identification is good. Conflict resolution errors could use more guidance.
Bug: "NullPointerException" will be thrown when invoking method "getName()" src/User.java:42 Why is this an issue? When "user" is null (see line 38), calling getName() will throw. Effort: 5min
Code Smell: Refactor this function to reduce its Cognitive Complexity from 23 to the 15 allowed.
Bug and vulnerability reports with data flow analysis showing exactly how the issue can be triggered.
Code smell messages cite metrics without showing which specific code patterns are driving the score up.
Analysis depth is impressive for bugs and vulnerabilities. Code smell messages feel too metric-driven and not actionable enough.
SB_BUILDER-VITE_0001: Storybook could not detect your project type. Please set the "framework" field in your .storybook/main.ts: framework: '@storybook/react-vite'
Cannot find module '@storybook/react' from 'src/Button.stories.tsx'
v7+ errors with SB_ prefixed codes include the exact config change needed.
Dependency and bundler errors pass through without Storybook-level interpretation. Webpack/Vite config conflicts are painful.
Storybook 7+ errors dramatically improved over v6. Framework detection and config errors are now excellent. Build errors still pass through raw.
warn - The `content` option in your Tailwind CSS configuration is missing or empty. warn - Configure your content sources or your generated CSS will be empty. warn - https://tailwindcss.com/docs/content-configuration
The 'bg-blue-950' class does not exist. If 'bg-blue-950' is a custom class, make sure it is defined within a @layer directive.
Content configuration warnings with doc links prevent the most common setup mistake.
Missing class errors don't distinguish between typos, wrong version, and genuinely custom classes.
v3 errors are solid. The IntelliSense plugin catches most issues in the editor before you even see terminal warnings.
✘ [ERROR] Could not resolve "node:crypto"
The package "node:crypto" was not found on the file system, and is not a known Node.js built-in.
Hint: Enable Node.js compatibility with:
compatibility_flags = ["nodejs_compat"]
in your wrangler.toml✘ [ERROR] A request to the Cloudflare API failed. workers.api.error.script_too_large [code: 10027]
Node.js compatibility errors with exact wrangler.toml config to fix them are excellent developer experience.
API errors pass through with numeric codes but no inline explanation or size/limit details.
wrangler v3 errors are a big improvement. Local dev errors are great. Deployment API errors are still terse and require code lookup.
VercelPostgresError: VercelPostgresError - 'missing_connection_string': You did not supply a 'connectionString' and no 'POSTGRES_URL' env var was found.
VercelPostgresError: VercelPostgresError - 'invalid_connection_string': The connection string is not a valid URL.
Missing config errors list both the programmatic and env var approaches to provide the value.
Connection string format errors don't show the expected format or an example.
Thin wrapper around Neon with Vercel-specific error codes for config issues. Postgres errors pass through from Neon unchanged.
AppwriteException: User (role: guests) missing scope (account) code: 401 type: general_unauthorized_scope
AppwriteException: Document with the requested ID already exists. code: 409 type: document_already_exists
Typed error codes (general_unauthorized_scope, document_already_exists) are searchable and machine-readable.
Self-hosted Docker errors during setup mix Appwrite errors with raw Docker/Traefik errors — hard to distinguish.
Consistent error structure across all SDK methods. Error types are descriptive. Self-hosted setup errors are the weak point.
x Could not find "build" in turbo.json pipeline.
If you want to run "build" as a task, add it to turbo.json:
{
"tasks": {
"build": {}
}
}WARNING: "NEXT_PUBLIC_API_URL" is included in "dependsOn" but is not listed in "env". Add it to the "env" key of the "build" task in turbo.json.
Missing task and env var errors include the exact turbo.json snippet needed to fix them.
Cache miss reasons could be more detailed — 'cache miss' doesn't explain which input changed.
Turbo's errors are surprisingly good for a build tool. Config mistakes are caught early with actionable fixes. Cache debugging could improve.
TRPCClientError: No "query"-procedure on path "user.getById"
at TRPCClientError.from (client.js:78)TRPCError: UNAUTHORIZED message: "You must be logged in to do this"
Router path in errors (user.getById) maps 1:1 to your source code. No guessing which procedure failed.
Zod input validation errors lose their structure when passed through tRPC — you get a flat message string instead of the full ZodError.
Works well for procedure-level errors. Input validation error formatting is a known pain point — consider using error formatters to preserve Zod structure.
UpstashError: ERR wrong number of arguments for 'set' command
UpstashError: Unauthorized
Redis command errors are faithful passthroughs — familiar and unambiguous for Redis users.
Authentication errors are bare 401s with no additional context about what credential is invalid.
Functional but minimal. Auth errors need improvement. Rate limit errors include the limit values which is helpful.
AxiomError: Dataset 'my-logs' does not exist. Create it at https://app.axiom.co/datasets
AxiomError: Request failed with status 422: field '_time' is required
Resource-not-found errors link directly to the dashboard section where you create the resource.
Ingest format errors are terse — field name is given but expected format/type is not.
Above average for an observability tool. The SDK wraps HTTP errors cleanly. Query errors from APL could be more descriptive.
PayloadError: The collection "products" does not exist. Check your payload.config.ts and ensure the slug matches.
ValidationError: The following field(s) failed validation: - title: This field is required - price: Value must be a number
Collection-not-found errors reference the config file directly — great for new users who mistype slugs.
Plugin compatibility errors can be cryptic when two plugins conflict in payload.config.ts.
Solid for a CMS. REST API errors are clean and consistent. Admin UI surfaces validation errors properly.
error: column "users.email" does not exist at /node_modules/postgres/cjs/src/connection.js:783:26 Code: 42703
DrizzleError: Cannot use `relations` with `one` without specifying fields and references.
Schema-time errors mention which table and field is misconfigured.
Runtime SQL errors pass through unchanged from the underlying driver.
Quality depends on which driver. drizzle-kit migration errors are clearer than runtime errors.
ApiError: 422 {"detail":"Input validation failed","errors":{"prompt":["This field is required"]}}Prediction failed: CUDA out of memory. Tried to allocate 24.00 GiB. GPU 0 has a total capacity of 23.69 GiB.
API errors are structured by field. Prediction logs are streamed back as part of the error.
Model-specific errors leak underlying framework messages (PyTorch, transformers) without translation.
Quality depends on model author. Replicate-managed models tend to have cleaner errors than community uploads.
{
"errors": [
{
"status": "404",
"title": "Not Found",
"detail": "The requested store could not be found"
}
]
}{
"errors": [
{
"status": "422",
"source": {"pointer": "/data/attributes/price"},
"detail": "Price must be greater than zero"
}
]
}JSON:API spec compliance gives consistent shape across every endpoint.
Webhook delivery error messages in dashboard are less detailed than API responses.
Standard-compliant errors mean tools that speak JSON:API work out of the box.
CohereAPIError: 400 {"message":"too many tokens. Please specify a shorter prompt."}CohereAPIError: 429 {"message":"trial token rate limit exceeded, limit is 100 requests per minute","reason":"trial_token_rate_limit_exceeded"}Rate limit errors distinguish trial from production limits clearly.
Token-count errors don't include actual usage numbers.
Improving with v2 API. Rerank and embed errors are more specific than chat errors.
{"error": "Code: 47, e.displayText() = DB::Exception: Missing columns: 'user_id' while processing query (version 23.x.x)"}{"error":"Pipe 'top_users' has no published endpoint"}Tinybird-layer errors are clear; underlying ClickHouse errors retain their codes for advanced debugging.
Some ClickHouse exception messages leak through with C++-style internals.
Pipe and Data Source errors are well-designed; raw query errors depend on ClickHouse quality.
StackClientError: Missing NEXT_PUBLIC_STACK_PROJECT_ID environment variable. Get it from your Stack Auth dashboard.
StackServerError: Invalid API key
Setup errors reference the dashboard and specific env var names.
API errors sometimes lack context — just status code and generic message.
Getting better with each release. Setup errors are good, runtime errors need more context.
TypeError: app.get is not a function // This often means you imported Hono incorrectly
[hono/validator] Validation failed: - body.email: Expected string, received undefined
Validator middleware errors are structured with field paths and expected types.
Framework-level errors are often raw TypeErrors — no Hono-specific context.
Minimalist framework means minimal error handling. Validation middleware is the exception — it's well-designed.
DrizzleError: No database connection. Make sure to pass a database client to drizzle(). Example: const db = drizzle(client)
error: column "user_id" does not exist
Setup errors include code examples showing correct usage.
SQL-level errors pass through raw from the database driver — no Drizzle context added.
Drizzle Kit migration errors are clearer than ORM runtime errors. SQL transparency means you get database errors directly.
LibsqlError: SQLITE_CONSTRAINT: UNIQUE constraint failed: users.email
Error: Failed to connect to database: unauthorized
SQL errors carry SQLite error codes and constraint details.
Connection and auth errors are vague — 'unauthorized' or 'connection refused' without guidance.
SQL-level errors are as good as SQLite itself. Connection layer errors need improvement. turso CLI errors are better.
LangfuseError: Failed to flush events. Status 401: Invalid API key. Check your LANGFUSE_SECRET_KEY.
LangfuseError: Trace not found: trace_abc123
Auth errors name the specific environment variable to check.
SDK silently drops events on network errors by default — no error visible.
SDK is designed to not crash your app — errors are logged, not thrown. Good for production but bad for debugging.
HatchetError: Workflow "order-processing" step "charge-payment" failed Error: Payment declined
gRPC Error: UNAVAILABLE: failed to connect to worker. Is the Hatchet engine running?
Workflow step errors include the full workflow/step path.
gRPC transport errors leak raw codes without user-friendly context.
Dashboard visualization of workflow failures is helpful. SDK errors are improving but gRPC layer needs wrapping.
OramaError: Property "title" is defined as "string" in schema but received "number"
OramaError: Cannot search on property "content" — not indexed. Indexed properties: title, description
Schema validation errors name the exact property and show expected vs received types.
Vector search dimension mismatches give a numeric error without explaining embedding model expectations.
Schema-driven errors are excellent. Vector/hybrid search errors need more context about embedding dimensions.
error: syntax error at or near "SELEC" at character 1
Error: Extension "pgvector" is not available. Available extensions: uuid-ossp, pg_trgm
Extension availability errors list what's actually available in the WASM build.
WASM initialization errors are opaque — memory and browser compatibility issues give generic failures.
You get real Postgres errors — same quality as any Postgres instance. WASM layer errors are the weak point.
ElectricError: Shape subscription failed: table "messages" does not exist or is not electrified. Run: ALTER TABLE messages ENABLE ELECTRIC;
SyncError: Conflict detected on row messages/abc123. Local write rejected.
Setup errors include the exact SQL command to fix the issue.
Sync conflict errors are vague about what conflicted and how to resolve.
Setup and schema errors are helpful. Sync-layer errors (conflicts, connectivity) need more context for debugging.
{
"error": "validation_error",
"detail": [{ "loc": ["body", "price_amount"], "msg": "value is not a valid integer", "type": "type_error.integer" }]
}{
"error": "not_found",
"detail": "Product not found"
}Validation errors use FastAPI format with field paths and type info.
404 errors are generic — just 'not found' without the resource ID.
API is built on FastAPI — you get its validation error quality for free. Custom errors are less detailed.
{
"error": {
"message": "Model 'gpt-4' is not available. Available models: llama3.3-70b, llama-4-scout-17b-16e",
"type": "invalid_request_error"
}
}{
"error": {
"message": "Rate limit exceeded",
"type": "rate_limit_error"
}
}Model errors list available alternatives.
Rate limit errors lack retry timing and usage context.
Follows OpenAI error format which is familiar. Missing some helpful metadata that OpenAI and OpenRouter include.
FirebaseError: Missing or insufficient permissions.
FirebaseError: Firebase: Error (auth/email-already-in-use).
Firebase Auth has great namespaced error codes (auth/weak-password, auth/user-not-found).
Firestore 'Missing or insufficient permissions' tells you nothing about which rule failed or why.
Auth errors: good. Firestore rules errors: terrible. Cloud Functions errors: depends on the day. No consistency across products.
Error: Invalid reference on main.tf line 15, in resource "aws_instance" "web": 15: ami = var.ami_id A reference to a variable which has not been declared.
Error: Error creating EC2 instance: InvalidParameterCombination: The architecture 'arm64' of the specified instance type is incompatible with the architecture 'x86_64' of the specified AMI.
HCL syntax errors with file:line and code snippet are genuinely useful.
Provider errors pass through raw cloud API errors with no Terraform-level guidance on how to fix your config.
Syntax errors: decent. Provider errors: raw passthrough from cloud APIs. State lock errors are terrifying.
MongoServerError: E11000 duplicate key error collection: mydb.users index: email_1 dup key: { email: "test@test.com" }MongooseError: Operation `users.find()` buffering timed out after 10000ms
Duplicate key errors clearly show which index and value conflicted.
Connection/buffering errors hide the real problem (no connection) behind timeout language.
Wide range: duplicate key errors are great, ObjectId cast errors are confusing, connection errors are misleading.
{"statusCode":403,"error":"Forbidden","message":"You are not allowed to call this endpoint.","errorCode":"insufficient_scope"}Callback URL mismatch. http://localhost:3000/api/auth/callback is not in the list of allowed callback URLs.
Callback URL mismatch errors actually show the offending URL.
Redirect loops with no error — just infinite redirects and a blank page. Silent failures are the worst.
Auth0's worst sin: silent redirect loops. When errors DO show, they're okay but rarely tell you the fix.
LibsqlError: SQLITE_CONSTRAINT_UNIQUE: UNIQUE constraint failed: users.email code: 'SQLITE_CONSTRAINT_UNIQUE'
LibsqlError: SERVER_ERROR: request error: connection refused code: 'SERVER_ERROR'
SQLite constraint and query errors pass through with proper SQLite error codes that are well-documented.
Network and replication errors collapse into generic SERVER_ERROR with no distinction between auth, connectivity, and config problems.
SQLite layer errors are clear; Turso infrastructure errors are vague. Embedded/local SQLite mode has better errors than cloud mode.
Build failed Error: unable to find any supported files in /app Make sure your application is in the root of the repository.
Deployment crashed Exit code: 137
Build detection errors explain what Nixpacks expected and how to configure it.
Runtime crashes show exit codes with no interpretation. OOM kills (137) and segfaults look identical to normal crashes.
Build errors are decent. Runtime errors are bare exit codes. No in-dashboard guidance on common failures.
Your service is using more than 512 MB of RAM. Consider upgrading to a higher plan.
Build failed: exit status 1 ==> Check the logs above for more details
Infrastructure limit errors (memory, disk) are clearly communicated with current vs allowed values.
Build failures report 'exit status 1' and redirect you to logs without highlighting the relevant section.
Better than raw exit codes but not by much. No error codes, no doc links. Dashboard surfacing of errors needs work.
Error: failed to fetch an image or build from source: error building: failed to solve: failed to compute cache key: failed to calculate checksum of ref: "/app/package.json": not found
Error: Machines in app 'my-app' are in an unrecoverable state. Run `fly apps restart my-app` to attempt recovery.
flyctl errors that suggest a fix command (fly apps restart, fly scale, fly secrets set) are helpful.
Docker build errors pass through with nested 'failed to' chains. Machine health check failures are cryptic.
CLI-level errors vary widely. Some suggest fixes, others pass through raw Docker/OCI errors. Health check failures need more context.
{
"errors": [{
"extensions": { "path": "$.selectionSet.users.selectionSet.posts", "code": "validation-failed" },
"message": "field 'posts' not found in type: 'users'"
}]
}{
"errors": [{
"extensions": { "code": "permission-error" },
"message": "check constraint of an insert/update permission has failed"
}]
}GraphQL validation errors with JSON path are useful for debugging complex nested queries.
Permission errors are the worst — no indication of which rule failed or what value was rejected.
Query validation errors are decent. Permission and relationship errors are frustratingly vague. Metadata apply errors can be cryptic.
{
"errors": [{
"message": "The from address does not match a verified Sender Identity.",
"field": "from.email",
"help": "http://sendgrid.com/docs/for-developers/sending-email/sender-identity/"
}]
}{
"errors": [{
"message": "Permission denied, wrong credentials",
"field": null,
"help": null
}]
}Validation errors with field names and help links guide you to the specific configuration needed.
Authentication errors are generic. API key scope issues look identical to wrong credentials.
Uneven quality. Sender verification errors are decent. Auth and rate limit errors lack specificity. Acquired by Twilio but error quality didn't improve.
(.gitlab-ci.yml): jobs:deploy config contains unknown keys: enviroment Did you mean: environment?
ERROR: Job failed: exit code 1
YAML validation errors with typo detection and suggestions are excellent.
Script execution failures show only the exit code. The actual error is buried in job logs with no highlighting.
Config validation is good. Runtime errors are just exit codes. Pipeline visualization helps trace which job failed but error messages don't.
Error: Unable to parse config:
in .circleci/config.yml, line 15, column 3:
- run: echo "hello
^
found unexpected end of streamToo long with no output (exceeded 10m0s): context deadline exceeded
YAML parsing errors with line:column and caret positioning are useful.
Timeout and resource errors lack step context and don't suggest config fixes (no_output_timeout, resource_class).
Config validation is decent. Execution errors are bare. Orb-related errors (version conflicts, missing parameters) can be very confusing.
Error: column "user_id" is of type integer but expression is of type text Hint: You will need to rewrite or cast the expression.
Error: Cannot read properties of undefined (reading 'columns')
at Object.<anonymous> (/node_modules/drizzle-kit/dist/index.js:1:9876)SQL-level errors from migrations are passed through cleanly from the database.
Schema introspection errors expose internal JS errors with no user-facing message or file location.
Drizzle ORM query errors are fine. drizzle-kit CLI errors are rough — schema mistakes yield cryptic internal errors rather than helpful messages.
[PostHog] Error sending events: Network request failed
PostHogError: Invalid API key 'phc_...' for project. Check your PostHog project settings.
API key validation error is clear and links to the right place.
Analytics event failures fail silently in many SDKs — no feedback about dropped events, no retry indication.
Client-side analytics errors are inherently low priority, but PostHog's SDK makes it hard to know when capture is broken.
<ErrorResponse>
<Error>
<Type>Sender</Type>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
</Error>
<RequestId>A1B2C3D4E5F6</RequestId>
</ErrorResponse>An error occurred (InvalidParameterValueException) when calling the CreateFunction operation: Unzipped size must be smaller than 262144000 bytes
Request IDs are always present, which helps when contacting support.
IAM AccessDenied with zero context about which permission or policy is blocking you. The #1 time sink in AWS.
AWS errors are a rite of passage. AccessDenied is the most useless error in all of cloud computing.
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on 127.0.0.53:53: server misbehaving
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied
Build step errors at least show which Dockerfile line failed.
Socket/daemon connection errors are a wall of URL-encoded paths and nested protocol errors.
Docker errors feel like reading raw syscall output. Permission denied is a 200-char sentence when it should be one line.
The Deployment "web" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"web"}: `selector` does not match template `labels`0/3 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/not-ready: }, 2 node(s) didn't match Pod's node affinity/selector.kubectl describe output at least groups events chronologically so you can trace what happened.
Scheduling errors with taints, tolerations, and affinity rules produce incomprehensible messages.
K8s errors assume you have a PhD in distributed systems. Even experienced devs Google every other error.
The Wall of Shame
The worst error messages in production. These cost developers millions of hours combined.
<ErrorResponse>
<Error>
<Type>Sender</Type>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
</Error>
<RequestId>A1B2C3D4E5F6</RequestId>
</ErrorResponse>S3 GetObject with wrong IAM permissions
Access Denied. That's it. Which permission? Which policy? Which resource ARN? Go read 47 IAM docs pages.
FirebaseError: Missing or insufficient permissions.
Firestore read blocked by security rules
Which rule? Which path? Which condition failed? This is the Firestore equivalent of AWS AccessDenied.
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on 127.0.0.53:53: server misbehaving
Docker pull with DNS issues
DNS resolution failed but the error is a nested chain of technical jargon. 'server misbehaving' is not actionable.
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied
Running docker without sudo
The classic. URL-encoded socket paths, nested error chain. Just say 'add your user to the docker group'.
0/3 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/not-ready: }, 2 node(s) didn't match Pod's node affinity/selector.Pod stuck in Pending state
Untolerated taint? Node affinity selector? This is a scheduling failure but reads like an alien language to most devs.
Deployment crashed Exit code: 137
Service running out of memory
Exit code 137 means OOM kill. Railway should say 'your service ran out of memory — upgrade your plan or check memory usage' but instead shows a raw exit code.
{
"errors": [{
"extensions": { "code": "permission-error" },
"message": "check constraint of an insert/update permission has failed"
}]
}Insert blocked by row-level permissions
Which permission? Which check constraint? Which field violated it? This tells you nothing actionable about your permission config.
ERROR: Job failed: exit code 1
Script step returning non-zero exit code
Exit code 1. That's it. Which command? What output? You have to scroll through the full job log to find the actual error.
Error: Cannot read properties of undefined (reading 'columns')
at Object.<anonymous> (/node_modules/drizzle-kit/dist/index.js:1:9876)Invalid schema export in drizzle.config.ts
Internal stack trace with no indication of what you did wrong. Could be any number of schema mistakes. Hours of debugging await.