Skip to content

fix/inline config parse on large build inputs#8118

Draft
kanej wants to merge 5 commits intomainfrom
fix/inline-config-parse-on-large-build-inputs
Draft

fix/inline config parse on large build inputs#8118
kanej wants to merge 5 commits intomainfrom
fix/inline-config-parse-on-large-build-inputs

Conversation

@kanej
Copy link
Copy Markdown
Member

@kanej kanej commented Apr 9, 2026

This PR reproduces the issue of inline config parsing failing on large enough build infos.

To run and end to end test that reproduces the failure based on our fork of base contracts (https://github.com/popescuoctavian/base-contracts/tree/migrate-to-HH3), then:

# Ensure foundry is installed - the devcontainer now sets it up
pnpm e2e exec --scenario ./end-to-end/base-contracts

This will, eventually generate this output:

# ... lots of setup and compilation taking a long time

An unexpected error occurred:

Error: Cannot create a string longer than 0x1fffffe8 characters
    at TextDecoder.decode (node:internal/encoding:494:28)
    at bytesToUtf8String (/tmp/end-to-end/base-contracts/node_modules/.pnpm/@nomicfoundation+hardhat-utils@4.0.2/node_modules/@nomicfoundation/hardhat-utils/src/bytes.ts:59:28)
    at collectRawOverrides (/tmp/end-to-end/base-contracts/node_modules/.pnpm/hardhat@3.3.0/node_modules/hardhat/src/internal/builtin-plugins/solidity-test/inline-config/index.ts:157:7)
    at getTestFunctionOverrides (/tmp/end-to-end/base-contracts/node_modules/.pnpm/hardhat@3.3.0/node_modules/hardhat/src/internal/builtin-plugins/solidity-test/inline-config/index.ts:55:27)
    at runSolidityTests (/tmp/end-to-end/base-contracts/node_modules/.pnpm/hardhat@3.3.0/node_modules/hardhat/src/internal/builtin-plugins/solidity-test/task-action.ts:172:33)
    at async runSolidityTests (/tmp/end-to-end/base-contracts/node_modules/.pnpm/hardhat@3.3.0/node_modules/hardhat/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.ts:43:5)
    at async Promise.all (index 0)
    at async main (/tmp/end-to-end/base-contracts/node_modules/.pnpm/hardhat@3.3.0/node_modules/hardhat/src/internal/cli/main.ts:221:26)
    at async file:///tmp/end-to-end/base-contracts/node_modules/.pnpm/hardhat@3.3.0/node_modules/hardhat/dist/src/cli.js:21:1 {
  code: 'ERR_STRING_TOO_LONG'
}

If you think this is a bug in Hardhat, please report it here: https://hardhat.org/report-bug
[e2e] Error: Command failed: pnpm hardhat test solidity
 ELIFECYCLE  Command failed with exit code 1.

Approach

First this PR replicates the issue with an end to end scenario by:

  • supporting pnpm to our end to end test scenarios
  • adding foundry to the devcontainer setup
  • adding a ./end-to-end/base-contracts scenario pointing at our fork where we found the issue (i.e. popescuoctavian/base-contracts)

Second this PR demonstrates one approach to the fix, implemented by Claude:

The inline config parser crashed with ERR_STRING_TOO_LONG on large codebases (e.g. base/contracts) because collectRawOverrides converted the entire build info output (~898MB) from Uint8Array to a JS string via bytesToUtf8String before passing it to JSON.parse, exceeding Node's ~512MB string limit. This PR replaces that with readJsonFileAsStream from hardhat-utils, which already exists and uses @streamparser/json-node to stream-parse the JSON from disk without ever creating a single large string. The BuildInfoAndOutput type is extended with buildInfoOutputPath to thread the file path through to the parser, and getTestFunctionOverrides becomes async accordingly.

This does resolve the immediate error from JSON.parse at the cost of a second read from the build info file.

pnpm version-for-release
pnpm e2e clean --scenario ./end-to-end/base-contracts
pnpm e2e exec --scenario ./end-to-end/base-contracts

# ... lots of setup, cloning, installing, compiling but eventually ...

[e2e] === Running: pnpm hardhat test solidity ===

Running Solidity tests

Error HHE807: Invalid inline config key "default.isolate" in project/test/L2/CrossL2Inbox.t.sol:CrossL2Inbox_ValidateMessage_Test#testFuzz_validateMessage_succeeds. Valid keys are: fuzz.runs, fuzz.maxTestRejects, fuzz.showLogs, fuzz.timeout, invariant.runs, invariant.depth, invariant.failOnRevert, invariant.callOverride, invariant.timeout, allowInternalExpectRevert

For more info go to https://hardhat.org/HHE807 or run Hardhat with --show-stack-traces
[e2e] Error: Command failed: pnpm hardhat test solidity --no-compile
 ELIFECYCLE  Command failed with exit code 1.

Fixes #8117.

Copilot AI review requested due to automatic review settings April 9, 2026 12:47
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 9, 2026

🦋 Changeset detected

Latest commit: 00e080f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
hardhat Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an end-to-end scenario intended to reproduce inline-config parsing failures on very large Solidity build-info outputs (base-contracts), along with harness support needed to run it (pnpm + Foundry in the devcontainer).

Changes:

  • Add Foundry installation to the devcontainer setup script.
  • Extend end-to-end scenario schema/types/validation to support pnpm (including tests).
  • Add a new end-to-end/base-contracts scenario with a preinstall script that pulls required Foundry deps.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
scripts/setup.sh Installs Foundry (forge) during devcontainer creation to support Foundry-based scenarios.
scripts/end-to-end/types.ts Adds pnpm as an allowed scenario package manager type.
scripts/end-to-end/schema/scenario.schema.json Updates JSON schema enum to allow pnpm.
scripts/end-to-end/schema/scenario-schema.ts Updates runtime validation to accept pnpm.
scripts/end-to-end/schema/scenario-schema.test.ts Adds a test covering pnpm; updates unsupported-PM test value.
end-to-end/base-contracts/scenario.json Introduces a new external-repo scenario for base-contracts using pnpm.
end-to-end/base-contracts/preinstall.sh Preinstall script that installs Foundry dependencies and checks out specific library versions.

Comment thread scripts/setup.sh
Comment thread scripts/end-to-end/schema/scenario-schema.test.ts Outdated
Comment thread end-to-end/base-contracts/scenario.json
Copilot AI review requested due to automatic review settings April 9, 2026 13:16
@kanej kanej added no docs needed This PR doesn't require links to documentation no peer bump needed labels Apr 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Comment on lines +134 to +137
const outputJsonString = JSON.stringify(outputJson);
const buildInfoOutputPath = join(tmpdir(), `${randomUUID()}.json`);
writeFileSync(buildInfoOutputPath, outputJsonString);

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

makeBuildInfo writes a JSON file into the OS temp directory but nothing deletes it after the test run. Over time (or with repeated CI retries) this can accumulate temp files and waste disk space; consider deleting these files in the tests (e.g., track returned buildInfoOutputPaths and remove them in an after/afterEach hook) or generate them in a per-test temp dir that is cleaned up automatically.

Copilot uses AI. Check for mistakes.
kanej added 3 commits April 9, 2026 13:24
The base/contracts repo uses pnpm as the package manager, to support
pulling this in as a scenario we are adding `pnpm` as a package manager
choice in scenario files.
@kanej kanej force-pushed the fix/inline-config-parse-on-large-build-inputs branch from eff588f to 3b16f4d Compare April 9, 2026 13:24
@kanej kanej force-pushed the fix/inline-config-parse-on-large-build-inputs branch from 3b16f4d to 00e080f Compare April 9, 2026 13:32
Copilot AI review requested due to automatic review settings April 9, 2026 13:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment on lines +156 to 158
const buildInfoOutput = await readJsonFileAsStream<SolidityBuildInfoOutput>(
buildInfoAndOutput.buildInfoOutputPath,
);
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

collectRawOverrides re-reads buildInfoOutputPath from disk even though getBuildInfosAndOutputs already loaded output into memory. For large build-info outputs this doubles I/O and can noticeably slow down test startup. Consider parsing from the already-loaded Uint8Array using a streaming JSON parser (e.g., piping a Readable.from(buildInfoAndOutput.output) into the same JSONParser used by readJsonFileAsStream), or refactoring getBuildInfosAndOutputs to avoid eagerly reading output when only inline-config extraction needs it.

Copilot uses AI. Check for mistakes.
Comment thread scripts/setup.sh
npm install -g bun

# Install forge
curl -L https://foundry.paradigm.xyz | bash
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The Foundry install step uses curl -L ... | bash without failing on HTTP errors. Using curl -fsSL (or at least -f) will make the setup fail fast if the download fails (e.g., transient network issues or a non-200 response) instead of piping an error page into bash.

Suggested change
curl -L https://foundry.paradigm.xyz | bash
curl -fsSL https://foundry.paradigm.xyz | bash

Copilot uses AI. Check for mistakes.
@alcuadrado
Copy link
Copy Markdown
Member

Some important datapoint: this doesn't happen anymore in HH 3.4.0.
It's not that it can't happen, but I wouldn't jump into this solution that will have a performance hit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no docs needed This PR doesn't require links to documentation no peer bump needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

inline config parsing failure for large code bases

3 participants