Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
510cc9f
sample implementation
simsonraj Feb 25, 2025
68efb67
Pulling the x-error-groups from open-rpc package
simsonraj Apr 20, 2025
b7da3a7
updated gastsby & docs generator
simsonraj Apr 27, 2025
46a9906
few fixes
simsonraj May 10, 2025
623c57a
Merge pull request #1 from simsonraj/error_groups
simsonraj May 10, 2025
2500734
Merge branch 'ethereum:main' into main
simsonraj May 10, 2025
721f190
Update scripts/build.js
simsonraj May 13, 2025
3bd6d47
meta data extension
simsonraj Jun 29, 2025
4eacff2
Merge pull request #2 from simsonraj/error_groups
simsonraj Jun 29, 2025
53d5577
sample implementation
simsonraj Feb 25, 2025
554443e
Pulling the x-error-groups from open-rpc package
simsonraj Apr 20, 2025
d3f6f22
updated gastsby & docs generator
simsonraj Apr 27, 2025
8d1dd3c
few fixes
simsonraj May 10, 2025
50113ef
Update scripts/build.js
simsonraj May 13, 2025
fc8aacc
meta data extension
simsonraj Jun 29, 2025
1ded1ed
Merge pull request #4 from simsonraj/sync_main_again
simsonraj Aug 29, 2025
019a359
fix package conflicts
simsonraj Aug 29, 2025
2b7da45
fix packages
simsonraj Aug 29, 2025
9b06027
Merge pull request #5 from simsonraj/sync_main_again
simsonraj Aug 29, 2025
5c8daea
extended error categories & code ranges implementation
simsonraj Sep 1, 2025
4019acd
Added TXPOOL errors, README file and fixes
simsonraj Sep 26, 2025
527bb9a
Added context in README
simsonraj Sep 26, 2025
89f012f
Update src/extensions/components/txpool-errors.yaml
simsonraj Oct 19, 2025
75fb065
Update src/extensions/components/txpool-errors.yaml
simsonraj Oct 19, 2025
d3948f7
Update src/extensions/components/txpool-errors.yaml
simsonraj Oct 19, 2025
490218e
Update src/extensions/components/txpool-errors.yaml
simsonraj Oct 19, 2025
8ab56cf
updated & re-organized error ranges & codes after review
simsonraj Oct 25, 2025
bc78032
fix ranges
simsonraj Oct 27, 2025
f77a8f7
Removed Data & Updated Message for errors
simsonraj Nov 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
"@graphql-inspector/core": "~3.3.0",
"@open-rpc/generator": "^2.1.0",
"@open-rpc/schema-utils-js": "^2.1.2",
"@open-rpc/extensions": "^0.0.2",
"@open-rpc/specification-extension-spec": "^1.0.2",
"@open-rpc/meta-schema": "^1.14.2",
"gatsby": "^5.14.3",
"graphql": "~16.3.0",
"graphql-request": "~4.1.0",
Expand Down
34 changes: 34 additions & 0 deletions scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from "fs";
import yaml from "js-yaml";
import mergeAllOf from "json-schema-merge-allof";
import { dereferenceDocument } from "@open-rpc/schema-utils-js";
import { XErrorGroupsJSON } from "@open-rpc/extensions";

function sortByMethodName(methods) {
return methods.slice().sort((a, b) => {
Expand Down Expand Up @@ -79,6 +80,37 @@ schemaFiles.forEach(file => {
};
});

let extensionSpecs = [];

// Enhance the existing XErrorGroupsJSON extension with conditional validation for different error categories
const enhancedErrorGroupSchema = JSON.parse(fs.readFileSync('src/extensions/schemas/x-error-category-ranges.json', 'utf8'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just going to write this here for tracking purposes, that this works as a stopgap until we on the OpenRPC side have a better story for being able to apply extensions to json pointer references. If we have that then there's no need to overwrite the error group spec. You'll able to just push the two specs, here but we're still a little ways from that.

XErrorGroupsJSON.schema = enhancedErrorGroupSchema;

extensionSpecs.push(XErrorGroupsJSON);

let extensions = [];
let extensionsBase = "src/extensions/components/"
let extensionsFiles = fs.readdirSync(extensionsBase);
extensionsFiles.forEach(file => {
console.log(file);
let raw = fs.readFileSync(extensionsBase + file);
let parsed = yaml.load(raw);
extensions.push(parsed);
});

// if extensions key matches with extensionSpecs name, then add it to an array of extensionSpec name
let extensionsDef = {};
extensionSpecs.forEach((extensionSpec) => {
extensions.forEach((extension) => {
if (extension.hasOwnProperty(extensionSpec.name)) {
extensionsDef[extensionSpec.name] ={
...extensionsDef[extensionSpec.name],
...extension[extensionSpec.name]
}
}
});
});

const doc = {
openrpc: "1.2.4",
info: {
Expand All @@ -91,7 +123,9 @@ const doc = {
version: "0.0.0"
},
methods: sortByMethodName(methods),
"x-extensions": extensionSpecs,
components: {
...extensionsDef,
schemas: schemas
}
}
Expand Down
8 changes: 7 additions & 1 deletion scripts/validate.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import fs from "fs";
import {
parseOpenRPCDocument,
dereferenceDocument,
validateOpenRPCDocument
} from "@open-rpc/schema-utils-js";
import OpenrpcDocument from "@open-rpc/meta-schema";

let rawdata = fs.readFileSync("openrpc.json");
let openrpc = JSON.parse(rawdata);

const error = validateOpenRPCDocument(openrpc);
/** @type {OpenrpcDocument} */
const document = openrpc;
const dereffed = await dereferenceDocument(document);

const error = validateOpenRPCDocument(dereffed);
if (error != true) {
console.log(error.name);
console.log(error.message);
Expand Down
12 changes: 12 additions & 0 deletions src/eth/submit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
required: true
schema:
$ref: '#/components/schemas/GenericTransaction'
x-error-group:
- $ref: '#/components/x-error-group/JSONRPCNonStandardErrors'
- $ref: '#/components/x-error-group/JSONRPCStandardErrors'
- $ref: '#/components/x-error-group/GasErrors'
- $ref: '#/components/x-error-group/ExecutionErrors'
- $ref: '#/components/x-error-group/TxPoolErrors'
result:
name: Transaction hash
schema:
Expand Down Expand Up @@ -45,6 +51,12 @@
required: true
schema:
$ref: '#/components/schemas/bytes'
x-error-group:
- $ref: '#/components/x-error-group/JSONRPCNonStandardErrors'
- $ref: '#/components/x-error-group/JSONRPCStandardErrors'
- $ref: '#/components/x-error-group/GasErrors'
- $ref: '#/components/x-error-group/ExecutionErrors'
- $ref: '#/components/x-error-group/TxPoolErrors'
result:
name: Transaction hash
schema:
Expand Down
113 changes: 113 additions & 0 deletions src/extensions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Extensions overview

## Proposal
#### Goal
A standard for JSON-RPC error codes & ship a shared catalog of JSON-RPC error codes and messages for EVM clients to unlock consistent tooling and developer ergonomics.

#### Motivation
Client implementations and EVM-compatible chains currently reuse codes or return generic error messages, making cross-client debugging brittle.

#### Solution
The solution incorporates [OpenRPC's extension schemas](https://github.com/open-rpc/specification-extension-spec) feature, specifically `x-error-group` [extension](https://github.com/open-rpc/tools/blob/main/packages/extensions/src/x-error-groups/x-error-groups.json), so common scenarios can be bundled into reusable categories, each backed by a reserved range of **200 codes** between **-31999 and -30000** (outside the JSON-RPC 2.0 reserved bands).
With the error grouping and inline provisioning offered by the extension schemas, we could onboard methods over time with granular control over the errors or groups each method would need to handle without copy pasting in the final spec.

The corresponding PR definition frames these groups as the canonical vocabulary for wallets, infra providers, and execution clients.

## Solution Layout
- `components/` – YAML fragments exposing each error family as an OpenRPC `x-error-group` definition.
- `schemas/x-error-category-ranges.json` – Extension to official `x-error-groups` that enforces the reserved integer windows per category during validation.
- This is to achieve inbuild validation of the reserved ranges per category using native `minimum` & `maximum` properties of the extended schema.
- Validation happens while running `scripts/validate.js` after building the final `refs-openrpc.json` / `openrpc.json`.
- `scripts/build.js` – Loads the schema above, augments the `XErrorGroupsJSON` extension, and merges the groups into `refs-openrpc.json` / `openrpc.json`.

## Implemented Methods
Currently, only below methods import all the error groups via `$ref` and may include inline method-specific codes while still inheriting the standard set.
- `eth_sendTransaction` in `src/eth/submit.yaml`
- `eth_sendRawTransaction` in `src/eth/submit.yaml`


## Reserved ranges at a glance
| Extension group | Category label | Reserved range | Source |
| --- | --- | --- | --- |
| JSON-RPC standard || $-32768$ to $-32000$ | JSON-RPC 2.0 spec |
| JSON-RPC non-standard | Client-specific | $-32099$ to $-32000$ | JSON-RPC 2.0 addendum |
| Gas errors | `GAS_ERRORS` | $-31999$ to $-31800$ | `gas-error-groups.yaml` |
| Execution errors | `EXECUTION_ERRORS` | $-31799$ to $-31600$ | `execution-errors.yaml` |
| (Future) consensus || $-31599$ to $-31400$ |
| (Future) networking || $-31399$ to $-31200$ |
| TxPool errors | `TXPOOL_ERRORS` | $-31199$ to $-31000$ | `txpool-errors.yaml` |


**Validation** of these bands happens through `XErrorGroupsJSON.schema` in `scripts/build.js`, so build failures flag any out-of-range additions early.


## Extending the catalog
1. Pick or create a YAML fragment under `components/` and add the new entry with `code`, `message`, `data`, and `x-error-category` per the proposal.
2. Stay within the reserved window; the JSON Schema guard in `schemas/x-error-category-ranges.json` will break the build if you drift.
3. Reference the group from the relevant method spec via `$ref: '#/components/x-error-group/<GroupName>'` and layer any bespoke errors inline.
4. Run the documentation build (e.g. `node scripts/build.js`) to regenerate `refs-openrpc.json` / `openrpc.json` and confirm validation passes.

Following this flow keeps the execution client surface aligned with the standard and preserves interoperability for downstream consumers.


## Catalog reference

### [JSON-RPC standard errors](https://www.jsonrpc.org/specification) (`rpc-standard-errors.yaml`)
| Code | Message | Notes |
| --- | --- | --- |
| $-32700$ | Parse error | An error occurred on the server while parsing the JSON text |
| $-32600$ | Invalid request | The JSON sent is not a valid request object |
| $-32601$ | Method not found | The method does not exist / is not available |
| $-32602$ | Invalid params | Invalid method parameter(s) |
| $-32603$ | Internal error | Internal JSON-RPC error |

### [JSON-RPC non-standard errors](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md) (`rpc-non-standard-errors.yaml`)
| Code | Message | Notes |
| --- | --- | --- |
| $-32000$ | Invalid input | Missing or invalid parameters |
| $-32001$ | Resource not found | Requested resource not found |
| $-32002$ | Resource unavailable | Requested resource not available |
| $-32003$ | Transaction rejected | Transaction creation failed |
| $-32004$ | Method not supported | Method is not implemented |
| $-32005$ | Limit exceeded | Request exceeds defined limit |
| $-32006$ | JSON-RPC version not supported | Version of JSON-RPC protocol is not supported |

### Gas errors (`gas-error-groups.yaml`)
| Code | Message | Data |
| --- | --- | --- |
| $-31800$ | GAS_TOO_LOW | Transaction gas is too low / intrinsic gas too low |
| $-31801$ | OUT_OF_GAS | The transaction ran out of gas |
| $-31802$ | GAS_PRICE_TOO_LOW | Gas price too low / gas price below configured minimum gas price |
| $-31803$ | BLOCK_GAS_LIMIT_EXCEEDED | Tx gas limit exceeds max block gas limit / intrinsic gas exceeds gas limit |
| $-31804$ | FEE_CAP_EXCEEDED | Tx fee exceeds cap / max priority fee per gas higher than max fee per gas |
| $-31805$ | GAS_OVERFLOW | Gas overflow error |
| $-31806$ | INSUFFICIENT_TRANSACTION_PRICE | Transaction price must be greater than base fee / max fee per gas less than block base fee |
| $-31807$ | INVALID_MAX_PRIORITY_FEE_PER_GAS | Max priority fee per gas higher than $2^{256}-1$ |
| $-31808$ | INVALID_MAX_FEE_PER_GAS | Max fee per gas higher than $2^{256}-1$ |
| $-31809$ | INSUFFICIENT_FUNDS | Insufficient funds for gas * price + value |
| $-31810$ | TRANSACTION_UNDERPRICED | Transaction's gas price is below the minimum for txpool |
| $-31811$ | REPLACEMENT_TRANSACTION_UNDERPRICED | Replacement transaction is sent without the required price bump |

### Execution errors (`execution-errors.yaml`)
| Code | Message | Data |
| --- | --- | --- |
| $-31600$ | NONCE_TOO_LOW | Transaction nonce is lower than the sender account's current nonce |
| $-31601$ | NONCE_TOO_HIGH | Transaction nonce is higher than the sender account's current nonce |
| $-31602$ | EXECUTION_REVERTED | Execution is reverted by REVERT Opcode |
| $-31603$ | INVALID_OPCODE | An invalid opcode was encountered during execution |
| $-31604$ | OUT_OF_COUNTERS | Not enough step counters to continue the execution |

### TxPool errors (`txpool-errors.yaml`)
| Code | Message | Data |
| --- | --- | --- |
| $-31000$ | ALREADY_KNOWN | Transaction is already known to the transaction pool |
| $-31001$ | INVALID_SENDER | Transaction sender is invalid |
| $-31002$ | INVALID_SIGNATURE | Transaction signature is invalid |
| $-31003$ | TXPOOL_FULL | Transaction pool is full |
| $-31004$ | NEGATIVE_VALUE | Transaction with negative value |
| $-31005$ | OVERSIZED_DATA | Transaction input data exceeds the allowed limit |
| $-31006$ | SENDER_BLACKLISTED | Transaction sender is blacklisted |
| $-31007$ | RECEIVER_BLACKLISTED | Transaction receiver is blacklisted |
| $-31008$ | CHAIN_ID_MISMATCH | Transaction chain ID does not match the expected chain ID |
| $-31009$ | TX_NOT_PERMITTED | Transaction is protected and cannot be permitted for unauthorized users |
| $-31010$ | INVALID_RLP_DATA | Transaction Data contains invalid RLP encoding |
22 changes: 22 additions & 0 deletions src/extensions/components/execution-errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
x-error-group:
ExecutionErrors:
- code: -31600
message: "NONCE_TOO_LOW"
data: "Transaction nonce is lower than the sender account's current nonce"
x-error-category: "EXECUTION_ERRORS"
- code: -31601
message: "NONCE_TOO_HIGH"
data: "Transaction nonce is higher than the sender account's current nonce"
x-error-category: "EXECUTION_ERRORS"
- code: -31602
message: "EXECUTION_REVERTED"
data: "Execution is reverted by REVERT Opcode"
x-error-category: "EXECUTION_ERRORS"
- code: -31603
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this error condition exists here?

Copy link
Contributor

@macfarla macfarla Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#600 just merged has reverted error code = 3 which contradicts this. will this value change?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will fix this as per our last RPC call, it will still be code = 3

message: "INVALID_OPCODE"
data: "An invalid opcode was encountered during execution"
x-error-category: "EXECUTION_ERRORS"
- code: -31604
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with this one, what is the meaning of this particular code? The term "step counters" has no defined meaning in Ethereum.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is ZK stack specific, I will move this out to a separate category

message: "OUT_OF_COUNTERS"
data: "Not enough step counters to continue the execution"
x-error-category: "EXECUTION_ERRORS"
50 changes: 50 additions & 0 deletions src/extensions/components/gas-error-groups.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
x-error-group:
GasErrors:
- code: -31800
message: "GAS_TOO_LOW"
data: "Transaction gas is too low / intrinsic gas too low"
x-error-category: "GAS_ERRORS"
- code: -31801
message: "OUT_OF_GAS"
data: "The transaction ran out of gas"
x-error-category: "GAS_ERRORS"
- code: -31802
message: "GAS_PRICE_TOO_LOW"
data: "Gas price too low / gas price below configured minimum gas price"
x-error-category: "GAS_ERRORS"
- code: -31803
message: "BLOCK_GAS_LIMIT_EXCEEDED"
data: "Tx gas limit exceeds max block gas limit / intrinsic gas exceeds gas limit"
x-error-category: "GAS_ERRORS"
- code: -31804
message: "FEE_CAP_EXCEEDED"
data: "Tx fee exceeds cap / max priority fee per gas higher than max fee per gas"
x-error-category: "GAS_ERRORS"
- code: -31805
message: "GAS_OVERFLOW"
data: "Gas overflow error"
x-error-category: "GAS_ERRORS"
- code: -31806
message: "INSUFFICIENT_TRANSACTION_PRICE"
data: "Transaction price must be greater than base fee / max fee per gas less than block base fee"
x-error-category: "GAS_ERRORS"
- code: -31807
message: "INVALID_MAX_PRIORITY_FEE_PER_GAS"
data: "Max priority fee per gas higher than 2^256-1"
x-error-category: "GAS_ERRORS"
- code: -31808
message: "INVALID_MAX_FEE_PER_GAS"
data: "Max fee per gas higher than 2^256-1"
x-error-category: "GAS_ERRORS"
- code: -31809
message: "INSUFFICIENT_FUNDS"
data: "Insufficient funds for gas * price + value"
x-error-category: "GAS_ERRORS"
- code: -31810
message: "TRANSACTION_UNDERPRICED"
data: "Transaction's gas price is below the minimum for txpool"
x-error-category: "GAS_ERRORS"
- code: -31811
message: "REPLACEMENT_TRANSACTION_UNDERPRICED"
data: "Replacement transaction is sent without the required price bump."
x-error-category: "GAS_ERRORS"
23 changes: 23 additions & 0 deletions src/extensions/components/rpc-non-standard-errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
x-error-group:
JSONRPCNonStandardErrors:
- code: -32000
message: "Invalid input"
data: "Missing or invalid parameters"
- code: -32001
message: "Resource not found"
data: "Requested resource not found"
- code: -32002
message: "Resource unavailable"
data: "Requested resource not available"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the meaning of these two codes? These are very generic errors. I suggest we drop these, since they are not meaningful.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- code: -32003
message: "Transaction rejected"
data: "Transaction creation failed"
- code: -32004
message: "Method not supported"
data: "Method is not implemented"
- code: -32005
message: "Limit exceeded"
data: "Request exceeds defined limit"
- code: -32006
message: "JSON-RPC version not supported"
data: "Version of JSON-RPC protocol is not supported"
17 changes: 17 additions & 0 deletions src/extensions/components/rpc-standard-errors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
x-error-group:
JSONRPCStandardErrors:
- code: -32700
message: "Parse error"
data: "An error occurred on the server while parsing the JSON text"
- code: -32600
message: "Invalid request"
data: "The JSON sent is not a valid request object"
- code: -32601
message: "Method not found"
data: "The method does not exist / is not available"
- code: -32602
message: "Invalid params"
data: "Invalid method parameter(s)"
- code: -32603
message: "Internal error"
data: "Internal JSON-RPC error"
Loading