truffle icon indicating copy to clipboard operation
truffle copied to clipboard

SyntaxError: Unexpected token in JSON at position

Open nidhhoggr opened this issue 2 years ago • 5 comments

Issue

This is possible related to https://github.com/trufflesuite/truffle/issues/3755

The issue is that a migration fails with the following error:


SyntaxError: Unexpected token  in JSON at position 236402
    at JSON.parse (<anonymous>)
    at FS.getContractName (/usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/sources/fs.js:47:1)
    at FS.require (/usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/sources/fs.js:25:1)
    at /usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/resolver.js:52:1
    at Array.forEach (<anonymous>)
    at Resolver.require (/usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/resolver.js:51:1)
    at Object.require (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:165:1)
    at ResolverIntercept.require (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/ResolverIntercept.js:22:1)
    at /vagrant/BattleSpeciesContracts/truffle/migrations/1_deploy_contracts.js:1:38
    at Script.runInContext (vm.js:144:12)
    at Object.file (/usr/lib/node_modules/truffle/build/webpack:/packages/require/dist/index.js:90:1)
    at Migration._load (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:42:1)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at Migration.run (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:202:1)
    at Object.runMigrations (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:142:1)
    at Object.runFrom (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:107:1)
    at Object.run (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:91:1)
    at module.exports (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/runMigrations.js:10:1)
    at module.exports (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/setUpDryRunEnvironmentThenRunMigrations.js:37:1)
    at Object.module.exports [as run] (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/run.js:33:1)
    at runCommand (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/command-utils.js:201:1)
Truffle v5.5.29 (core: 5.5.29)
Node v14.18.3

Steps to Reproduce

truffle migrate

Actual Results

In troubleshooting the issue I found that the following code is responsible for throwing the error:

    getContractName(sourcePath, searchPath = this.contractsBuildDirectory) {
        const contractsBuildDirFiles = fs_1.default.readdirSync(searchPath);
        const filteredBuildArtifacts = contractsBuildDirFiles.filter((file) => file.match(".json") != null);
        for (const buildArtifact of filteredBuildArtifacts) {
              const artifact = JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(searchPath, buildArtifact), "utf8").toString());
              if (artifact.sourcePath === sourcePath) {
                  return artifact.contractName;
              }
        }
        // fallback
        return path_1.default.basename(sourcePath, ".sol");
    }

What I was able to find is that the file in question generated in the /tmp directory has a bunch of null characters appended to the bottom of the JSON file which is the source of JSON.parse failing.

    "methods": {},
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  }
}^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@

Environment

  • Operating System: Linux localhost.localdomain 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018 x86_64 x86_64 x86_64 GNU/Linu Truffle v5.5.29 (core: 5.5.29) Ganache v7.4.0 Solidity - ^0.8.0 (solc-js) Node v14.18.3 Web3.js v1.7.4 NPM: 8.19.1

nidhhoggr avatar Sep 11 '22 00:09 nidhhoggr

Strangely enough, the issue resolved itself after rebooting my machine. The question is what is wrong with the code to be appending NUL bytes to the json artifacts based on my previous machine state? Closing for now.

nidhhoggr avatar Sep 11 '22 02:09 nidhhoggr

I spoke too soon. After deploying the contract to Goreli and rerunning a simple migration, the issues reoccurs.

Migration

const FirstContract = artifacts.require("FirstContract");


module.exports = async (deployer, network, addresses) => {
  console.log(FirstContract.address);
};

Output

1_deploy_contracts.js
=====================

/usr/lib/node_modules/truffle/build/4889.bundled.js:22560
              throw err;
              ^

SyntaxError: Unexpected token  in JSON at position 55786
    at JSON.parse (<anonymous>)
    at FS.getContractName (/usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/sources/fs.js:48:1)
    at FS.require (/usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/sources/fs.js:27:1)
    at /usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/resolver.js:54:1
    at Array.forEach (<anonymous>)
    at Resolver.require (/usr/lib/node_modules/truffle/build/webpack:/packages/resolver/dist/lib/resolver.js:52:1)
    at Object.require (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:165:1)
    at ResolverIntercept.require (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/ResolverIntercept.js:22:1)
    at /vagrant/BattleSpeciesContracts/truffle/migrations/1_deploy_contracts.js:1:38
    at Script.runInContext (vm.js:144:12)
    at Object.file (/usr/lib/node_modules/truffle/build/webpack:/packages/require/dist/index.js:90:1)
    at Migration._load (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:42:1)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at Migration.run (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/Migration.js:202:1)
    at Object.runMigrations (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:142:1)
    at Object.runFrom (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:107:1)
    at Object.run (/usr/lib/node_modules/truffle/build/webpack:/packages/migrate/index.js:91:1)
    at module.exports (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/runMigrations.js:10:1)
    at module.exports (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/setUpDryRunEnvironmentThenRunMigrations.js:37:1)
    at Object.module.exports [as run] (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/commands/migrate/run.js:33:1)
    at runCommand (/usr/lib/node_modules/truffle/build/webpack:/packages/core/lib/command-utils.js:201:1)
Truffle v5.5.29 (core: 5.5.29)
Node v14.18.3

Rebooting the machine fixes it again. But why do I have to keep rebooting my machine after every deployment?

nidhhoggr avatar Sep 11 '22 03:09 nidhhoggr

Hi @nidhhoggr, can you provide a git repo that reproduces this? The Issue reproduction steps doesn't specify truffle-config settings, migration files or contracts.

cds-amal avatar Sep 11 '22 16:09 cds-amal

Hello @cds-amal The migration file to trigger the error is in provided in a comment above. The truffle config doesn't have anything fancy from the standard convention. The issue of NUL bytes /0 being appended to the file happens when a buffer is overallocated for a string and gets converted back to a string. I was tracing through the code and suspect it's happening somewhere in the normalization functions which are responsible for Buffer conversions. It's not contract specific because it happens for multiple contracts including basic migration contracts. While all this would be taken with a grain of salt, I don't think providing a repo for you would be sufficient in replicating the issue but would rather need to be accompanied by a docker container. The reason for this is because it seems to be OS specific. When running truffle migrate outside of the vagrant instance the issue is not replicated. In my case I am using a CentOS7 box running on vagrant which I suspect to be the culprit. This vagrant instance however is my goto node.js development environment for several years and I have never ran into buffer conversion bugs. In any case, if you can give me some time to put that together. It would require me to replicate using a base repo that doesn't have any proprietary code in it. Thanks.

nidhhoggr avatar Sep 13 '22 02:09 nidhhoggr

This vagrant instance however is my goto node.js development environment for several years and I have never ran into buffer conversion bugs. In any case, if you can give me some time to put that together. It would require me to replicate using a base repo that doesn't have any proprietary code in it.

Oh, this would be very helpful. Thanks!

cds-amal avatar Sep 13 '22 02:09 cds-amal

Closing this one for issue maintenance. @nidhhoggr Whenever you're ready with the repro steps and if you're still running into this issue, feel free to open a new issue. Thanks!

cliffoo avatar Oct 13 '22 17:10 cliffoo