# New storage layout is incompatible: ContextUpgradeable.sol:36: Inserted \`\_\_gap\`

**URL:** <https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371>\
**Category:** Upgrades\
**Tags:** proxies\
**Created:** [February 26, 2022, 11:52am UTC](https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371 "2022-02-26T11:52:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Garfield550](https://avatars.discourse-cdn.com/v4/letter/g/f4b2a3/32.png) [@Garfield550](https://forum.openzeppelin.com/u/Garfield550)\
**Post date:** [February 26, 2022, 11:52am UTC](https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371/1 "2022-02-26T11:52:39Z")

</div>

I'm new to OpenZeppelin and I try to wrote upgradeable contracts, when I upgrade contract, I getting this error:

```auto
An unexpected error occurred:

Error: New storage layout is incompatible

@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36: Inserted `__gap`
  > New variables should be placed after all existing inherited variables

```

#### 🔢 Code to reproduce

```auto
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;

import "hardhat/console.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

error GreeterError();

contract Greeter is Initializable {
    string public greeting;

    function initialize(string memory _greeting) public initializer {
        console.log("Deploying a Greeter with greeting:", _greeting);
        greeting = _greeting;
    }

    /// @custom:oz-upgrades-unsafe-allow constructor
    // solhint-disable-next-line no-empty-blocks
    constructor() initializer {}

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public {
        console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
        greeting = _greeting;
    }

    function throwError() external pure {
        revert GreeterError();
    }
}

```

```auto
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;

import "hardhat/console.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

error GreeterError();

contract GreeterV2 is Initializable, OwnableUpgradeable {
    string public greeting;

    function initialize(string memory _greeting) public initializer {
        console.log("Deploying a Greeter with greeting:", _greeting);
        greeting = _greeting;
        __Ownable_init();
    }

    /// @custom:oz-upgrades-unsafe-allow constructor
    // solhint-disable-next-line no-empty-blocks
    constructor() initializer {}

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public onlyOwner {
        console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
        greeting = _greeting;
    }

    function throwError() external pure {
        revert GreeterError();
    }
}

```

```ts
import { task } from "hardhat/config";
import { TaskArguments } from "hardhat/types";
import { Greeter } from "../../types";

task("deploy:Greeter")
  .addParam("greeting", "Say hello, be nice")
  .setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) {
    const greeterFactory = await ethers.getContractFactory("Greeter");
    const greeter = <Greeter>(
      await upgrades.deployProxy(greeterFactory, [taskArguments.greeting], { initializer: "initialize" })
    );
    await greeter.deployed();
    console.log("Greeter deployed to: ", greeter.address);
  });

task("upgrade:Greeter")
  .setAction(async function (_, { ethers, upgrades }) {
    const greeterV1 = await ethers.getContractAt("Greeter", "0xXAddressX");
    const greeterV2Factory = await ethers.getContractFactory("GreeterV2");
    await upgrades.upgradeProxy(greeterV1, greeterV2Factory);
    console.log("Greeter upgraded");
  });

```

#### 💻 Environment

Hardhat: 2.8.4  
@openzeppelin/contracts-upgradeable: 4.5.1

---

<div class="post-metadata">

**Author:** ![ericglau](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ericglau/32/15149_2.png) [@ericglau](https://forum.openzeppelin.com/u/ericglau)\
**Post date:** [February 28, 2022, 4:45pm UTC](https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371/2 "2022-02-28T16:45:09Z")

</div>

Hi @Garfield550,

When upgrading a contract, the new version must not have storage layout conflicts with the previous version. This includes storage slots used by parent contracts. There are some examples of storage layout conflicts here: [https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#modifying-your-contracts](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#modifying-your-contracts)

In your example, the first version does not extend `OwnableUpgradeable`, but defines `string public greeting;`.

However, the second version extends [`OwnableUpgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v4.5.1/contracts/access/OwnableUpgradeable.sol) (which extends [`ContextUpgradeable`](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/v4.5.1/contracts/utils/ContextUpgradeable.sol)).

`ContextUpgradable` has a variable with some reserved storage `uint256[50] private __gap;`.  
`OwnableUpgradable` also has `address private _owner;` and `uint256[49] private __gap;`.

Since your contract has these as parents (transitively), those variables (with 100 storage slots combined) get inserted _before_ your own contract's `string public greeting;` variable, so this is a conflict.

The solution is to ensure you extend `OwnableUpgradable` in the first version of your contract as well, or declare enough unused storage slots in the first version if you might want to extend other contracts in the future (and then reduce the unused storage slots in the second version, corresponding to what is used by newly extended contracts).

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [March 2, 2022, 8:38pm UTC](https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371/3 "2022-03-02T20:38:19Z")

</div>

Another fix is to write your V2 like this:

```auto
contract GreeterV1Storage {
    string public greeting;
}

contract GreeterV2 is Initializable, GreeterV1Storage, OwnableUpgradeable {
    ...
}

```

This ensure V1's variables are not pushed further down in storage.

---

<div class="post-metadata">

**Author:** ![Mister\_Singh](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/mister_singh/32/15830_2.png) [@Mister\_Singh](https://forum.openzeppelin.com/u/Mister_Singh)\
**Post date:** [July 26, 2022, 7:41pm UTC](https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371/4 "2022-07-26T19:41:52Z")

</div>

@frangio could this approach of moving v1's storage into a contract like `GreeterV1Storage` and then inheriting it before inheriting `OwnableUpgradeable` fail when the contracts inherited before are more derived than the Storage one. Like i understand that inheritance contracts have to written most base to most derived and wont it be possible that we cant move items to a storage contract and inherit since it breaks this order.

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [August 1, 2022, 5:27pm UTC](https://forum.openzeppelin.com/t/new-storage-layout-is-incompatible-contextupgradeable-sol-inserted-gap/25371/5 "2022-08-01T17:27:42Z")

</div>

Yes, it isn't necessarily so straightforward to implement my suggestion. But I think it's definitely doable.
