Creating a tree fails with "Must supply a valid tree.mode"

The Github API for create-a-tree fails with Must supply a valid tree.mode for no apparent reason.

At first I was producing the payload by putting all the contents directly in the tree, i.e.

const tree = paths.map(function (path) {
  return {
    path,
    content: fs.readFileSync(path).toString(),
    mode: parseInt(fs.statSync(path).mode.toString(8), 10).toString(),
  }
})

That sometimes caused the JSON payload to be huge (because files had a lot of content in them) that I’d receive a HTTP 202 and it’d take a while for the API to process everything. When I got the Must supply a valid tree.mode with this approach, I thought the payload size was the issue, so I changed it to create blobs upfront and reference them by their SHA instead of inlining the content directly. i.e.

const blobs = []
for (const filePath of changedPaths) {
  const response = await github.git.createBlob({
    owner,
    repo,
    content: fs.readFileSync(filePath).toString(),
  })
  if (response.status === 201) {
    blobs.push({ filePath, sha: response.data.sha })
  }
}

const tree = blobs.map(function ({ filePath, sha }) {
  return {
    path: filePath,
    sha,
    mode: parseInt(fs.statSync(filePath).mode.toString(8), 10).toString(),
    type: "blob",
  }
})

That again did not work and I got the Must supply a valid tree.mode error once more.

At this point I’m unable to figure out why it doesn’t work. I am trying to create a tree on github.com/paritytech/substrate and my payload is following the tree items format, so the error does not make sense. I thought it could be a misleading error due to some nonexistent file being provided but that is not the case. Here’s a sample of an object list I sent which should be valid but fails with that error:

[
    {
      path: "Cargo.lock",
      sha: "4f7bce5aaa3c6ba8174209bb848d129637571170",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/build_spec_cmd.rs",
      sha: "78ad3b64724d9fb842b910e2b53f64b0edf17211",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/check_block_cmd.rs",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/export_blocks_cmd.rs",
      sha: "4153c80a0545e78574bb1cb7a35ec3a3aa3b1a45",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/export_state_cmd.rs",
      sha: "e154c3a502217df8186c2fffa6e9b95ba2c2684f",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/generate.rs",
      sha: "42214d2f5e45854884f565acc60d835bdd613b86",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/insert_key.rs",
      sha: "f166db85c15649225ea1b250d557e9359f8acd7a",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/purge_chain_cmd.rs",
      sha: "c61e21a6a5ad0a3872be0a1b3263f3586cdfdeb5",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/run_cmd.rs",
      sha: "9ef14cfa02b82c0afaa179acb85e0efb39b80a07",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/sign.rs",
      sha: "5d487861428fd5b7e5872eacd762d3a534667f44",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/vanity.rs",
      sha: "ce1f079db8789ce40bdf0c2a5154d887cb115c73",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/commands/verify.rs",
      sha: "c6ce3ef9d69c8855f43c92a83d6c3ed8af827381",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/database_params.rs",
      sha: "d468f155555624f372b5bb81ea178aaa32c9d59c",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/import_params.rs",
      sha: "a1d8c1f8834c2e1b40dec1245e071edcae1c6604",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/keystore_params.rs",
      sha: "2975c9bf5041f0df92e5b1b390112956c1984248",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/mod.rs",
      sha: "0769e5a87adcb2245173c9cd26cb3ae021704bd0",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/network_params.rs",
      sha: "7549c76378bea680e653a322a3b145783634e439",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/node_key_params.rs",
      sha: "d5823341aa69208e6e81c43c46589aac2e383320",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/offchain_worker_params.rs",
      sha: "a6d65e4027a25ea2eae809b6f6729945a30d7524",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/pruning_params.rs",
      sha: "32abaa9a755b4c2aac7a82e55135051de2cec89c",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/shared_params.rs",
      sha: "c0317c280a9d04a145002a9124ef2e6a9a37a061",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/cli/src/params/transaction_pool_params.rs",
      sha: "feea19c97c2d6fb28d80349b77dba007b43f6572",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc-api/Cargo.toml",
      sha: "662f4bd16fd4cc6724db0624892a2afb7eb074bf",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc-api/src/state/mod.rs",
      sha: "0ebc553b41178d178049dbb045baf63580e61861",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc-servers/src/lib.rs",
      sha: "be6abea67b055e32c005e955c3d5b51c46ff719f",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc/Cargo.toml",
      sha: "a352e5fc387bdf533c9cf50c4638fea50ef13fcf",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc/src/state/mod.rs",
      sha: "dc36c2f561e5e786e0285a7b221c5b118aa007d3",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc/src/state/state_full.rs",
      sha: "c75106512d338f438899d86975de70c238173e3e",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc/src/state/state_light.rs",
      sha: "21b99befc0515195704fa8be1fc0e15f3ce6c609",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/rpc/src/system/mod.rs",
      sha: "248c2dcfed3c6d50fcbc292d7ea0697b7e9f8f8c",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/service/src/client/call_executor.rs",
      sha: "b48ff028cda0ea23d229524efae93331ffbbba0d",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/service/src/client/wasm_override.rs",
      sha: "06a719c346ca66ac9312b1deb10a3360d181755a",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/tracing/Cargo.toml",
      sha: "a455cd8ab95c331919c29bd018032e69cd6e9fd0",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/tracing/src/block/mod.rs",
      sha: "70e74b1d827885dbaac4d3570b678ee5ad8e272b",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/tracing/src/lib.rs",
      sha: "72992a9ab05fa950cb87fe6e35ac016cbe1b8e47",
      mode: "100664",
      type: "blob",
    },
    {
      path: "client/tracing/src/logging/mod.rs",
      sha: "49bcfc4abfb4df51bfae4fe64ca0d5a0d9ba55b0",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/balances/src/weights.rs",
      sha: "35d51b5cc8a1ed003be27a6e85123d1a4b1611e5",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/election-provider-multi-phase/src/unsigned.rs",
      sha: "66b985c8efb9470978e0d680deb3bfbda5593376",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/im-online/src/benchmarking.rs",
      sha: "5ab4d16c7fe087c713b0da31331aa51eaaf151f6",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/im-online/src/lib.rs",
      sha: "0290c564ec599314c2a5f9ba6105b177472d9e89",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/im-online/src/tests.rs",
      sha: "5ce931875b9a67d391ad00c421b83f5807b11672",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/nicks/src/lib.rs",
      sha: "a6d2415ab96ef1b30760bf031a257582b1437078",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/offences/benchmarking/src/lib.rs",
      sha: "f65bdddd36d02cc83f25cb76f4b64da1acf3245c",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/support/test/tests/pallet.rs",
      sha: "3bde38c78e2c12ba344a12d5a8701cd5a1555a45",
      mode: "100664",
      type: "blob",
    },
    {
      path: "frame/system/src/lib.rs",
      sha: "c3fe688420097a6cf4e481075bb86dc69419d727",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/core/src/crypto.rs",
      sha: "f5b7606be558a63933db376f17f9563b481e7deb",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/rpc/Cargo.toml",
      sha: "9a502c99d311dd6097331efe1af8d419e8d9454f",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/rpc/src/lib.rs",
      sha: "ea7118479943d8934beba94f5d5400ce42046d8c",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/rpc/src/tracing.rs",
      sha: "1062ec1d9ebe5c4043076d10a02b376913eb8238",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/state-machine/Cargo.toml",
      sha: "79fccef08c199c5989c2f702c826eb428cf45e39",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/state-machine/src/ext.rs",
      sha: "43793d3c815dc956f922070d918a8c68f6031244",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/state-machine/src/lib.rs",
      sha: "a6f1fb1f0e7884a4d0e0263e6c0162978b0d1539",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/tracing/Cargo.toml",
      sha: "6c4d70b109cd7ae6d04966cd637c694d290a4780",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/tracing/README.md",
      sha: "d66bb90016c7184e7178d437ab6944e4e36faee2",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/tracing/src/lib.rs",
      sha: "95eb4d05667091f11e9d30198534be844fcd270c",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/tracing/src/types.rs",
      sha: "9fdcdfb5263991e2d32dc45a3ded199e3e12b4a3",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/utils/README.md",
      sha: "2da70f09ccbc5677d7a29ad5126998d8c945b77e",
      mode: "100664",
      type: "blob",
    },
    {
      path: "primitives/utils/src/lib.rs",
      sha: "6461361c96d1d988e380fbfe19258ae2a027a9c6",
      mode: "100664",
      type: "blob",
    },
    {
      path: "ss58-registry.json",
      sha: "a0d762f50eaebc880249a996bdd426f15ea70d6a",
      mode: "100664",
      type: "blob",
    },
  ]

Update: This has nothing to do with the amount of files. Even a single file in the tree is not working.

Hey @joao-paulo-parity :wave:

There’s a very slight typo in your mode value.

You have: mode: "100664" which should actually be "100644" for a blob type.