validate-chain-files.yml fails PRs on chain files those PRs never touched, and 8 files currently on
main cannot pass it. The two problems compound: the first decides who gets hit, the second decides
whether the run fails.
1. the changed-file list is "everything merged since the PR opened"
The workflow triggers on pull_request_target and computes:
git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }}
Under pull_request_target, github.sha is the base branch head, not the PR. So that diff is
base-when-the-PR-opened .. current main, which is every commit merged to main since the PR was
opened, and none of the PR's own commits.
On #3106, opened 2026-09-01 with base.sha 1640e92a, that window currently contains 27
constants/additionalChainRegistry/ files, all added by other people. The validator was handed all
27 and failed on two of them:
Validation failed for chainid-11941.js: Chain name should be an object
Validation failed for chainid-402.js: Chain chain is mandatory
Neither file is in #3106, whose diff is constants/extraRpcs.js and tests/check-duplicate-keys.js
only. The older the PR, the wider the window, which is why this shows up on the oldest open PR
touching extraRpcs.js and not on recent ones.
base.sha...head.sha with three dots, or the PR files API, would give the PR's own changes.
2. eight files on main fail the validator today
Replaying validateChainFile's own checks over all 511 registry files:
511 files 503 pass 8 FAIL
3 Chain icon is not a string chainid-101001000.js, chainid-11166111.js, chainid-193939.js
2 Chain name should be an object chainid-11941.js, chainid-1199.js
2 Chain networkId is mandatory chainid-202599.js, chainid-210000.js
1 Chain chain is mandatory chainid-402.js
Causes, and what each would need:
icon as an object. Those three carry icon: { url, format, width, height } while
stringCheck(data,'icon') wants a string. It looks deliberate rather than malformed, so this may be
the validator being stricter than the format you actually want to accept. Your call which side
changes; I have not touched them.
features as plain strings. ["EVM Compatible", "MetaMask Supported"] hits
features.forEach(f => stringCheck(f,'name',true)), whose first line rejects a non-object. Rewriting
as [{ "name": "EVM Compatible" }, { "name": "MetaMask Supported" }] preserves the content exactly
and is the form the other 509 files use.
- missing
networkId. Both JuChain files. ethereum-lists has authoritative values:
202599 -> networkId 202599, chain "JuChain", icon "ju-test" and
210000 -> networkId 210000, chain "JuChain", icon "ju".
- missing
chain. chainid-402.js (Actumic Mainnet). Not in ethereum-lists, so there is no
upstream value to copy and I will not invent one. Its shortName is actumic; tell me what chain
should read and I will add it.
reproducing the census
# replays stringCheck/numberCheck from .github/scripts/validate-chain-files.js
# over every constants/additionalChainRegistry/chainid-*.js
Happy to send a PR for the unambiguous subset (the two features rewrites plus the two JuChain
networkId values from upstream), which would clear 4 of the 8. The icon question and 402's chain
need a decision from you first, and fixing the workflow diff is the part that stops this recurring.
validate-chain-files.ymlfails PRs on chain files those PRs never touched, and 8 files currently onmain cannot pass it. The two problems compound: the first decides who gets hit, the second decides
whether the run fails.
1. the changed-file list is "everything merged since the PR opened"
The workflow triggers on
pull_request_targetand computes:git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }}Under
pull_request_target,github.shais the base branch head, not the PR. So that diff isbase-when-the-PR-opened .. current main, which is every commit merged to main since the PR wasopened, and none of the PR's own commits.
On #3106, opened 2026-09-01 with
base.sha 1640e92a, that window currently contains 27constants/additionalChainRegistry/files, all added by other people. The validator was handed all27 and failed on two of them:
Neither file is in #3106, whose diff is
constants/extraRpcs.jsandtests/check-duplicate-keys.jsonly. The older the PR, the wider the window, which is why this shows up on the oldest open PR
touching
extraRpcs.jsand not on recent ones.base.sha...head.shawith three dots, or the PR files API, would give the PR's own changes.2. eight files on main fail the validator today
Replaying
validateChainFile's own checks over all 511 registry files:Causes, and what each would need:
iconas an object. Those three carryicon: { url, format, width, height }whilestringCheck(data,'icon')wants a string. It looks deliberate rather than malformed, so this may bethe validator being stricter than the format you actually want to accept. Your call which side
changes; I have not touched them.
featuresas plain strings.["EVM Compatible", "MetaMask Supported"]hitsfeatures.forEach(f => stringCheck(f,'name',true)), whose first line rejects a non-object. Rewritingas
[{ "name": "EVM Compatible" }, { "name": "MetaMask Supported" }]preserves the content exactlyand is the form the other 509 files use.
networkId. Both JuChain files. ethereum-lists has authoritative values:202599 -> networkId 202599, chain "JuChain", icon "ju-test"and210000 -> networkId 210000, chain "JuChain", icon "ju".chain.chainid-402.js(Actumic Mainnet). Not in ethereum-lists, so there is noupstream value to copy and I will not invent one. Its
shortNameisactumic; tell me whatchainshould read and I will add it.
reproducing the census
Happy to send a PR for the unambiguous subset (the two
featuresrewrites plus the two JuChainnetworkIdvalues from upstream), which would clear 4 of the 8. Theiconquestion and 402'schainneed a decision from you first, and fixing the workflow diff is the part that stops this recurring.