Skip to main content
Glama
mahdibrr

dev-error-explainers

dev-error-explainers

npm version test license: MIT

Paste an error. Get a deterministic explanation.

No LLM · no API · no network · no telemetry

A Node.js ERR_REQUIRE_ESM error piped into npx dev-error-explainers, which prints the cause, three ranked fixes and the Node.js docs link

npm run build 2>&1 | npx dev-error-explainers
npm install dev-error-explainers
import { detect, explainEsmCjs } from 'dev-error-explainers';
const error = 'Error [ERR_REQUIRE_ESM]: require() of ES Module /app/node_modules/node-fetch/src/index.js from /app/index.js not supported.';
console.log(detect(error));
const { findings } = explainEsmCjs({ error, nodeVersion: '20.10.0' });
console.log(findings[0].title, findings[0].fixes.map((f) => f.title));

Output:

[ 'esm-cjs-explainer' ]
ERR_REQUIRE_ESM — require() of an ES module [
  'Upgrade Node.js (you are on 20.10.0)',
  'Use dynamic import() from CommonJS',
  'Convert the calling file to ESM'
]

Seven small, pure JavaScript modules with zero dependencies. Each one recognises the exact error text a developer pastes (from the browser console, npm, next build, curl -I, a Node.js stack trace…), explains why it happens, and returns concrete fixes with a link to the primary source where one exists (MDN, the Node.js docs, the npm docs, the PostgreSQL docs, the Supabase docs…). The same engine runs as a library, a CLI, a GitHub Action and an MCP server.

Secrets: the CLI, the Action and the MCP server pass the input through redact() before it is analysed, with one exception: the DATABASE_URL doctor reads the raw postgres:// line (a password's exact characters decide the diagnosis), and never prints that password. Used directly as a library, six of the seven modules mask what looks like a secret before echoing it back; the build-error decoder does not — it quotes the matching lines of your build output as they are. Redaction has limits: see what it does not catch.

Six of them power the free tools on iloveblogs.blog/tools, where you can try each one in the browser.

Module

Main export (dev-error-explainers)

What it explains

Try it live

cors-error-explainer

diagnoseCors

Chrome / Firefox / Safari "blocked by CORS policy" errors: missing or wrong Access-Control-Allow-* headers, preflight failures, credentials, mixed content — with a fix for your stack

CORS Error Explainer

esm-cjs-explainer

explainEsmCjs

ERR_REQUIRE_ESM, "Cannot use import statement outside a module", "exports is not defined in ES module scope", ERR_UNKNOWN_FILE_EXTENSION ".ts", ERR_MODULE_NOT_FOUND, ERR_PACKAGE_PATH_NOT_EXPORTED — aware of your Node.js version

ESM/CJS Error Explainer

npm-eresolve-explainer

analyseEresolveLog

npm ERR! ERESOLVE peer-dependency conflicts: who asks for which range, what is installed, and why they do not intersect

npm ERESOLVE Explainer

chunk-cache-explainer

diagnoseChunkCache

ChunkLoadError / "Loading chunk failed" after a deploy: reads your response headers and finds the stale HTML, the CDN cache hit or the SPA fallback

ChunkLoadError Cache Checker

database-url-doctor

diagnoseDatabaseUrl

Postgres / Supabase connection strings: pooler vs direct, port 5432 vs 6543, pgbouncer, SSL, unencoded password characters — with a corrected URL for Prisma, Drizzle, pg or psql

DATABASE_URL Doctor

build-error-decoder

decodeBuildError

Failing next build / next dev output: Suspense bailouts, dynamic server usage, window is not defined, hydration mismatches, module resolution, heap out of memory, EADDRINUSE…

Next.js Build Error Decoder

database-connection-explainer

explainDatabaseConnection

"Can't connect to the database" from Node.js apps on PostgreSQL: ECONNREFUSED (including ::1 localhost), ETIMEDOUT, ENOTFOUND, Prisma P1000 / P1001 / P1017, password authentication failed, no pg_hba.conf entry, too many clients, self-signed certificates. Generic network codes are only diagnosed next to a Postgres signal

No browser tool yet — rules and sources

Evidence: most findings cite the primary source they were checked against. The build-error decoder has no primary-source URL; its links point to articles on the author's site, iloveblogs.blog.

Node.js 20 or later. ES modules only.

Usage

Everything is available from the package root, and each module can also be imported on its own:

import { diagnose } from 'dev-error-explainers/cors-error-explainer';

const r = diagnose({
  error: "Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.",
});
r.isCorsProblem; // true
r.findings;      // what is wrong, why, and the source
r.fix;           // a fix for the detected (or guessed) stack
import {
  analyseEresolveLog, diagnoseDatabaseUrl, diagnoseChunkCache, decodeBuildError, explainDatabaseConnection,
} from 'dev-error-explainers';

analyseEresolveLog(npmOutput);                                        // { detected, code, conflicts: [...] }
diagnoseDatabaseUrl(process.env.DATABASE_URL, { client: 'prisma' }); // { ok, kind, findings, corrected }
diagnoseChunkCache({ htmlHeaders, chunkHeaders });                    // headers from `curl -I`
decodeBuildError(nextBuildOutput);                                    // matched rules, most severe first
explainDatabaseConnection({ error: stackTrace });                     // { recognised, findings, related }

detect(text)

Returns the names of the modules that recognise text, in a fixed order, or []. Each module is asked through its own recogniser — detect adds no heuristics of its own. Note that chunk-cache-explainer reads HTTP response headers (the output of curl -I), not the ChunkLoadError message itself; the message alone is recognised by build-error-decoder.

Related MCP server: Hivemind

JSON contract

Every module has its own result shape. diagnose(text) maps all of them onto one shape with stable rule ids, after redacting the input — the shape the CLI prints with --json, the GitHub Action renders and the MCP server returns:

import { diagnose } from 'dev-error-explainers'; // or 'dev-error-explainers/contract'

diagnose('FATAL:  password authentication failed for user "andym"');
// { version: '0.1', matched: true, redactions: 0,
//   results: [{ rule: 'database-connection.password-auth-failed', family: 'database-connection',
//               severity: 'critical', confidence: 'high', title, cause, fixes, evidence, module }] }

Unknown input gives { matched: false, results: [] } — never a closest guess. The shape, the full rule table, the confidence semantics and the redaction limits are in docs/CONTRACT.md. A public corpus of real pasted errors with their expected results lives in fixtures/, each case with its source. redact(text) is exported too (dev-error-explainers/redact).

CLI

Pipe a failing command into it, or pass a log file. Nothing is sent anywhere.

npm run build 2>&1 | npx dev-error-explainers
npx dev-error-explainers < error.log
npx dev-error-explainers --text "Error [ERR_REQUIRE_ESM]: require() of ES Module …" --node 18.17.0
npx dev-error-explainers --json < error.log     # the contract result (docs/CONTRACT.md)

Flags: --only cors|esm|eresolve|build|database-url|database-connection|chunk-cache, --json, --node <version>, --client prisma|drizzle|pg|psql, --html-headers <file> --chunk-headers <file>, --help, --version. npx dev-error-explainers mcp starts the MCP server.

Exit codes: 0 an error was recognised, 2 nothing recognised (nothing is guessed), 64 usage error. A connection string is always printed with its password masked.

Use it in CI (GitHub Action)

When a step fails, the Action reads the log you saved from it and writes the cause and the fix to the job summary, with annotations on the file and line when the log names a file in your checkout. No network, no LLM, no token.

      - name: Build
        id: build
        continue-on-error: true      # let the explain step run…
        shell: bash
        run: |
          set -o pipefail
          npm run build 2>&1 | tee build.log

      - name: Explain the failure
        if: steps.build.outcome == 'failure'
        uses: mahdibrr/dev-error-explainers@v0
        with:
          log-file: build.log

      - name: Fail the job if the build failed
        if: steps.build.outcome == 'failure'
        run: exit 1                  # …then keep the job red

Inputs, outputs and why pipefail and steps.build.outcome matter: docs/ACTION.md.

Use it from your AI assistant (MCP)

An MCP server with one tool, explain_error, so an assistant can check a pasted error against the documented cause before it guesses. Offline and deterministic; unrecognised input is reported as such. Claude Code:

claude mcp add dev-error-explainers -- npx -y -p dev-error-explainers dev-error-explainers-mcp

Claude Desktop, Cursor, VS Code and the protocol details: docs/MCP.md.

Use it in Claude Code (plugin: skill + MCP)

The repository is also a Claude Code plugin marketplace. The plugin bundles the MCP server and a skill that tells Claude when to call it:

/plugin marketplace add mahdibrr/dev-error-explainers
/plugin install dev-error-explainers@dev-error-explainers

Principles

  • Deterministic. The same input always gives the same answer; the rules are tested against real error text (Stack Overflow questions, GitHub issues, framework output).

  • Offline. Nothing is sent anywhere: the input never leaves the process.

  • Cited where possible. Findings link to the documentation that states the rule, where one exists — not every rule cites a source.

  • Honest about unknowns. An error the module does not recognise is reported as not recognised, never guessed.

Tests

npm install
npm test

CI runs the suite on Node.js 20, 22 and 24.

Contributing

Unrecognised error? Open an issue with the exact text. Paste the error as printed, the command that produced it, and the tool versions. A new rule needs a test built from a real error. A diagnosis that is wrong is a bug too — there is a separate template for that.

License

MIT

Available Tools

1 tool
explain_errorExplain a developer errorA
Read-onlyIdempotent

Explain a concrete developer error message or log excerpt and return its documented cause and fix.

Call it when the user pastes (or you captured from a terminal/browser console) an actual error, for example:

  • Node.js ESM/CommonJS errors: ERR_REQUIRE_ESM, ERR_MODULE_NOT_FOUND, "Cannot use import statement outside a module", "require is not defined in ES module scope".

  • npm ERESOLVE / peer-dependency conflict logs from npm install.

  • Next.js next build / next dev output (module not found, heap out of memory, server/client component errors, prerender failures).

  • Browser CORS console errors ("has been blocked by CORS policy", preflight, Access-Control-Allow-Origin).

  • A postgres:// or postgresql:// connection string (DATABASE_URL, Supabase pooler/direct URLs) that fails to connect.

  • Postgres connection errors from Node.js apps: connect ECONNREFUSED / ETIMEDOUT on 5432, getaddrinfo ENOTFOUND, Prisma P1000/P1001/P1017, "password authentication failed", "no pg_hba.conf entry", "too many clients", self-signed certificate. Pass the raw text verbatim, including the stack trace and the "Node.js vX" footer when present; do not paraphrase it.

Returns a short human-readable diagnosis (cause, why, ranked fixes with code, official source links) plus the same result as structured JSON. If nothing is recognised it answers "No known error recognised — nothing guessed"; then rely on your own reasoning.

Fully offline and deterministic: no network, no LLM, same input gives the same output. Secrets it can recognise (URL passwords, Bearer/Basic tokens, JWTs, token/key query parameters) are masked in the output.

ParametersJSON Schema
NameRequiredDescriptionDefault
errorYesThe raw error message or log excerpt, verbatim (max ~200 KB). Include the lines around the error: stack trace, npm log block, "Node.js vX" footer, or the full connection string.
clientNoOptional database client for connection-string advice (default prisma).
node_versionNoOptional Node.js version in use (e.g. "20.10.0"), used to tailor ESM/CommonJS advice. Usually detected from the error text itself.

Output Schema

ParametersJSON Schema
NameRequiredDescription
toolYesAlways "dev-error-explainers".
engineYesThe code path that produced the diagnosis (src/contract.js).
matchedYesTrue when at least one explainer recognised the input.
resultsYesOne Diagnosis per finding, most severe first (docs/CONTRACT.md); empty when matched is false.
versionYesPackage version that produced the result.
redactionsYesNumber of values masked in the output.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld=false, but the description adds material context beyond them: fully offline and deterministic, secret masking in output (URL passwords, Bearer/Basic tokens, JWTs), the exact 'No known error recognised' fallback string, and the dual human-readable + JSON return.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose, invocation trigger, and return/fallback behavior are front-loaded; the error-family bullet list is long but each bullet maps to a real supported category. Slightly verbose, but every line is load-bearing for the agent's routing decision.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return details are not strictly required, yet the description still names the two return formats and the unrecognised-error fallback. Combined with the usage examples and behavioral notes, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description goes beyond it by instructing that the raw text be passed verbatim including stack trace and Node footer, and clarifies node_version is usually auto-detected. That adds behavioral guidance the schema does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('explain a concrete developer error message or log excerpt') and scopes the output ('documented cause and fix'). Even with no siblings, the first sentence pins the tool's domain precisely enough that an agent can distinguish it from generic reasoning.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to call it ('when the user pastes ... an actual error') and enumerates the concrete error families it handles (Node ESM, npm ERESOLVE, Next.js, CORS, Postgres/Prisma). It also defines the failure path: if nothing is recognised, rely on your own reasoning.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev0.1.0
    • First observedexplain_error

TDQS

A4.6/5.0

Scored across 1 tool

Disambiguation5/5

There is only one tool, so there is no possibility of overlap or misselection between tools. Its purpose (diagnose a concrete developer error message) is clearly stated and distinguishable from any generic reasoning the agent might do.

Naming Consistency5/5

The single name explain_error follows a clean verb_noun convention and is self-descriptive. There are no other names to conflict with, so consistency is trivially satisfied.

Tool Count3/5

One tool is borderline thin for a server surface, even though it is well-scoped to a single capability. A single-tool server offers no granularity if callers want, e.g., just the structured or just the lookup.

Completeness4/5

For its narrow stated purpose (explain a pasted error and return cause, fixes, and structured JSON) the surface is self-contained, including an explicit no-match fallback. Coverage is only as broad as its offline known-error database, but no lifecycle operations are obviously missing.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Enables AI assistants to manage development workflows by running build commands, executing tests, analyzing package.json files, installing dependencies, and performing code linting. Supports multiple package managers (npm, yarn, pnpm) and provides detailed error reporting for development operations.
    5
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides instant access to a searchable knowledge base of 16,000+ community-driven troubleshooting solutions for common coding problems. Includes community feedback and smart ranking to help AI assistants find the most effective solutions.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides intelligent error detection and debugging capabilities across multiple programming languages with real-time monitoring of build, lint, runtime, console, and test errors. Offers AI-enhanced error analysis with automated resolution suggestions and context-aware debugging.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables LLM clients to inspect local dev environments—Docker container health, pnpm workspace integrity, and stuck process detection—without manual terminal copy-pasting.
    MIT