<p>The name <code>wrappedMintingPolicy</code> in the where statement is not indicated with the INLINABLE pragma. Maybe adding the line</p>
<p><code>{-# INLINEABLE wrappedMintingPolicy #-}</code></p>
<p>solves the problem.</p>

CC BY-SA 4.0
2022-03-24T13:41:49.103Z
If that was the case shouldn't I have the same error inside the ```makeThreadTokenLogic``` function?
Michele Nuzzi
CC BY-SA 4.0
2022-04-29T10:14:15.750Z
Maybe GHC applies the INLINEABLE hint to all where clauses as well. And then `wrappedMintingPolicy` is the only function not "covered by it".
Sebastian Nagel
CC BY-SA 4.0
2022-03-22T03:54:35.863Z
2022-03-22T03:54:35.863Z
Barros
<p>As a second answer, you can also try to inline <code>wrappedMintingPolicy</code> by hand by doing:</p>
<pre><code>threadTokenPolicy :: TTParams -&gt; Scripts.MintingPolicy
threadTokenPolicy params = Scripts.mkMintingPolicyScript (
        $$(PlutusTx.compile [|| \x -&gt; Scripts.wrapMintingPolicy @TTRedeemer (makeThreadTokenLogic x) ||])
        `PlutusTx.applyCode` PlutusTx.liftCode params
    )
</code></pre>

CC BY-SA 4.0
2022-04-29T10:15:04.457Z
2022-04-29T10:15:04.457Z
Sebastian Nagel
<p>I'm trying to  write a very simple NFT minting policy myself and I can't get rid of the following error</p>
<pre><code>Program error: GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
            No unfolding
            
Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy

Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                           @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                           
Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                           @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                           NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer

Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                           @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                           NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer
                           (NFTVM.Validator.ThreadTokenPolicy.makeThreadTokenLogic
                              utxo_ref' tn')

Context: Compiling expr: \ (tn' :: Plutus.V1.Ledger.Value.TokenName) -&gt;
                           Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                             @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                             NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer
                             (NFTVM.Validator.ThreadTokenPolicy.makeThreadTokenLogic
                                utxo_ref' tn')

Context: Compiling expr: \ (utxo_ref' :: Plutus.V1.Ledger.Tx.TxOutRef)
                           (tn' :: Plutus.V1.Ledger.Value.TokenName) -&gt;
                           Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                             @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                             NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer
                             (NFTVM.Validator.ThreadTokenPolicy.makeThreadTokenLogic
                                utxo_ref' tn')
</code></pre>
<p>reading <a href="https://cardano.stackexchange.com/a/4432/6763">this answer from a similar question</a> I understood that this kind of error rises when using a non-inlineable piece of code</p>
<p>from the error message I can also understand that the incriminated code is the following</p>
<pre><code>threadTokenPolicy :: TTParams -&gt; Scripts.MintingPolicy
threadTokenPolicy params = Scripts.mkMintingPolicyScript (
        $$(PlutusTx.compile [|| wrappedMintingPolicy ||])
        `PlutusTx.applyCode` PlutusTx.liftCode params
    )
    where
        wrappedMintingPolicy = Scripts.wrapMintingPolicy @TTRedeemer . makeThreadTokenLogic
</code></pre>
<p>and I can confirm my assumption since removing this part removes also the error</p>
<p>can anyone please explain to me which part is the &quot;non-inlineable&quot; part?</p>

I'll leave here the full code in case it can help having more context
<pre><code>{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings   #-}

{-# LANGUAGE NoImplicitPrelude   #-}

{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE NumericUnderscores  #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# LANGUAGE MultiParamTypeClasses #-}


module NFTVM.Validator.ThreadTokenPolicy (
    TTRedeemer(..), -- exporting the type and all his constructors ( Start and Close )
    makeThreadTokenLogic,
    threadTokenPolicy
    )
where

import qualified Plutus.V1.Ledger.Contexts as Ctx
    (
        ScriptContext, scriptContextTxInfo,
        ownCurrencySymbol,
        TxInfo, txInfoSignatories, txInfoMint
    )
import qualified Plutus.V1.Ledger.Value    as Value
    (
        CurrencySymbol,
        TokenName,
        flattenValue
    )
import qualified Plutus.V1.Ledger.Crypto   as Cryptography (PubKeyHash)-- CurrencySymbol
import qualified PlutusTx.Trace            as Trace (traceError, traceIfFalse)-- traceError , traceIfFalse
import qualified PlutusTx
    (
        makeLift,
        makeIsDataIndexed,
        compile, applyCode, liftCode
    )
import Ledger
    (
        scriptHashAddress,
        TxOutRef,
        TxInfo (txInfoInputs),
        TxInInfo (txInInfoOutRef),
        TokenName
    )
import qualified Ledger.Typed.Scripts      as Scripts
    (
        MintingPolicy, wrapMintingPolicy
    )
import qualified Ledger.Scripts            as Scripts
import           PlutusTx.Prelude          as Prelude
    (
        Bool (False), Integer,
        any, length,
        (==), (/=), (&amp;&amp;), (.), (!!),
        head, map, elem
    )
import PlutusTx (makeIsDataIndexed)


data TTParams = TTParams {
    getTokenName :: Value.TokenName,
    getUTxO :: Ledger.TxOutRef
}

PlutusTx.makeLift ''TTParams

data TTRedeemer = Start | Close

PlutusTx.makeIsDataIndexed ''TTRedeemer [
                                            ( 'Start , 0 ), -- Constr 0 [] -- means start, aka mints the thread NFT
                                            ( 'Close , 1 )  -- Constr 1 [] -- means close, aka burns the thread NFT
                                        ]

{-# INLINEABLE makeThreadTokenLogic #-}
makeThreadTokenLogic :: TTParams -&gt; TTRedeemer -&gt; Ctx.ScriptContext -&gt; Bool
makeThreadTokenLogic params action ctx =
    correctUTxO &amp;&amp;
    case action of
        Start -&gt; ensureTokenMinted
        Close -&gt; ensureTokenBurned
        _ -&gt; Trace.traceError &quot;unexpected redeemer&quot;
    where
        txInfos :: Ctx.TxInfo
        txInfos = Ctx.scriptContextTxInfo ctx

        correctUTxO :: Bool
        correctUTxO = getUTxO params `elem` map txInInfoOutRef (txInfoInputs txInfos)

        ensureOnlyThisTokenMinted_ForAmount :: Integer -&gt; Bool
        ensureOnlyThisTokenMinted_ForAmount amtToMint =
            case Value.flattenValue (Ctx.txInfoMint txInfos) of
                -- if the list contains only one minting policy
                [( currSym, tn, amt )] -&gt; amt == amtToMint &amp;&amp; currSym == Ctx.ownCurrencySymbol ctx &amp;&amp; getTokenName params == tn
                -- else fails
                _ -&gt;  Trace.traceError &quot;txInfoMint value contained more than 1 element; only 1 token minted is allowed&quot;

        ensureTokenMinted :: Bool
        ensureTokenMinted = ensureOnlyThisTokenMinted_ForAmount 1

        ensureTokenBurned :: Bool
        ensureTokenBurned = ensureOnlyThisTokenMinted_ForAmount (-1)

threadTokenPolicy :: TTParams -&gt; Scripts.MintingPolicy
threadTokenPolicy params = Scripts.mkMintingPolicyScript (
        $$(PlutusTx.compile [|| wrappedMintingPolicy ||])
        `PlutusTx.applyCode` PlutusTx.liftCode params
    )
    where
        wrappedMintingPolicy = Scripts.wrapMintingPolicy @TTRedeemer . makeThreadTokenLogic
</code></pre>

<h2>Update</h2>
<p>I do get the same error in the same kind of error compiling the <a href="https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs" rel="nofollow noreferrer"><code>Week05.NFT</code> code from the <code>plutus-pioneer-program</code></a>;
migth that be something wrong with any evironment configuration?</p>

<plutus><plutus-pioneer-program><smart-contract><plutustx><plutus-starter>
can't understand which part of the code is not "PlutusTx"
# can't understand which part of the code is not "PlutusTx"

(Asked by: username_0 on 2022-03-18)

I'm trying to  write a very simple NFT minting policy myself and I can't get rid of the following error
Program error: GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
            No unfolding
            
Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy

Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                           @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                           
Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                           @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                           NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer

Context: Compiling expr: Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                           @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                           NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer
                           (NFTVM.Validator.ThreadTokenPolicy.makeThreadTokenLogic
                              utxo_ref' tn')

Context: Compiling expr: \ (tn' :: Plutus.V1.Ledger.Value.TokenName) ->
                           Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                             @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                             NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer
                             (NFTVM.Validator.ThreadTokenPolicy.makeThreadTokenLogic
                                utxo_ref' tn')

Context: Compiling expr: \ (utxo_ref' :: Plutus.V1.Ledger.Tx.TxOutRef)
                           (tn' :: Plutus.V1.Ledger.Value.TokenName) ->
                           Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                             @ NFTVM.Validator.ThreadTokenPolicy.TTRedeemer
                             NFTVM.Validator.ThreadTokenPolicy.$fUnsafeFromDataTTRedeemer
                             (NFTVM.Validator.ThreadTokenPolicy.makeThreadTokenLogic
                                utxo_ref' tn')

reading this answer from a similar question I understood that this kind of error rises when using a non-inlineable piece of code
from the error message I can also understand that the incriminated code is the following
threadTokenPolicy :: TTParams -> Scripts.MintingPolicy
threadTokenPolicy params = Scripts.mkMintingPolicyScript (
        $$(PlutusTx.compile [|| wrappedMintingPolicy ||])
        `PlutusTx.applyCode` PlutusTx.liftCode params
    )
    where
        wrappedMintingPolicy = Scripts.wrapMintingPolicy @TTRedeemer . makeThreadTokenLogic

and I can confirm my assumption since removing this part removes also the error
can anyone please explain to me which part is the "non-inlineable" part?

I'll leave here the full code in case it can help having more context
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings   #-}

{-# LANGUAGE NoImplicitPrelude   #-}

{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE NumericUnderscores  #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# LANGUAGE MultiParamTypeClasses #-}


module NFTVM.Validator.ThreadTokenPolicy (
    TTRedeemer(..), -- exporting the type and all his constructors ( Start and Close )
    makeThreadTokenLogic,
    threadTokenPolicy
    )
where

import qualified Plutus.V1.Ledger.Contexts as Ctx
    (
        ScriptContext, scriptContextTxInfo,
        ownCurrencySymbol,
        TxInfo, txInfoSignatories, txInfoMint
    )
import qualified Plutus.V1.Ledger.Value    as Value
    (
        CurrencySymbol,
        TokenName,
        flattenValue
    )
import qualified Plutus.V1.Ledger.Crypto   as Cryptography (PubKeyHash)-- CurrencySymbol
import qualified PlutusTx.Trace            as Trace (traceError, traceIfFalse)-- traceError , traceIfFalse
import qualified PlutusTx
    (
        makeLift,
        makeIsDataIndexed,
        compile, applyCode, liftCode
    )
import Ledger
    (
        scriptHashAddress,
        TxOutRef,
        TxInfo (txInfoInputs),
        TxInInfo (txInInfoOutRef),
        TokenName
    )
import qualified Ledger.Typed.Scripts      as Scripts
    (
        MintingPolicy, wrapMintingPolicy
    )
import qualified Ledger.Scripts            as Scripts
import           PlutusTx.Prelude          as Prelude
    (
        Bool (False), Integer,
        any, length,
        (==), (/=), (&&), (.), (!!),
        head, map, elem
    )
import PlutusTx (makeIsDataIndexed)


data TTParams = TTParams {
    getTokenName :: Value.TokenName,
    getUTxO :: Ledger.TxOutRef
}

PlutusTx.makeLift ''TTParams

data TTRedeemer = Start | Close

PlutusTx.makeIsDataIndexed ''TTRedeemer [
                                            ( 'Start , 0 ), -- Constr 0 [] -- means start, aka mints the thread NFT
                                            ( 'Close , 1 )  -- Constr 1 [] -- means close, aka burns the thread NFT
                                        ]

{-# INLINEABLE makeThreadTokenLogic #-}
makeThreadTokenLogic :: TTParams -> TTRedeemer -> Ctx.ScriptContext -> Bool
makeThreadTokenLogic params action ctx =
    correctUTxO &&
    case action of
        Start -> ensureTokenMinted
        Close -> ensureTokenBurned
        _ -> Trace.traceError "unexpected redeemer"
    where
        txInfos :: Ctx.TxInfo
        txInfos = Ctx.scriptContextTxInfo ctx

        correctUTxO :: Bool
        correctUTxO = getUTxO params `elem` map txInInfoOutRef (txInfoInputs txInfos)

        ensureOnlyThisTokenMinted_ForAmount :: Integer -> Bool
        ensureOnlyThisTokenMinted_ForAmount amtToMint =
            case Value.flattenValue (Ctx.txInfoMint txInfos) of
                -- if the list contains only one minting policy
                [( currSym, tn, amt )] -> amt == amtToMint && currSym == Ctx.ownCurrencySymbol ctx && getTokenName params == tn
                -- else fails
                _ ->  Trace.traceError "txInfoMint value contained more than 1 element; only 1 token minted is allowed"

        ensureTokenMinted :: Bool
        ensureTokenMinted = ensureOnlyThisTokenMinted_ForAmount 1

        ensureTokenBurned :: Bool
        ensureTokenBurned = ensureOnlyThisTokenMinted_ForAmount (-1)

threadTokenPolicy :: TTParams -> Scripts.MintingPolicy
threadTokenPolicy params = Scripts.mkMintingPolicyScript (
        $$(PlutusTx.compile [|| wrappedMintingPolicy ||])
        `PlutusTx.applyCode` PlutusTx.liftCode params
    )
    where
        wrappedMintingPolicy = Scripts.wrapMintingPolicy @TTRedeemer . makeThreadTokenLogic

Update
I do get the same error in the same kind of error compiling the Week05.NFT code from the plutus-pioneer-program;
migth that be something wrong with any evironment configuration?

**Tags:** plutus, plutus-pioneer-program, smart-contract, plutustx, plutus-starter

---

## 2 answers

### Answer by username_1 on 2022-03-22. Score: 1

The name `wrappedMintingPolicy` in the where statement is not indicated with the INLINABLE pragma. Maybe adding the line

`{-# INLINEABLE wrappedMintingPolicy #-}`

solves the problem.

> **Comments:**
> **username_0**: If that was the case shouldn't I have the same error inside the ```makeThreadTokenLogic``` function?  
> **username_2**: Maybe GHC applies the INLINEABLE hint to all where clauses as well. And then `wrappedMintingPolicy` is the only function not "covered by it".  

---

### Answer by username_2 on 2022-04-29. Score: 0

As a second answer, you can also try to inline wrappedMintingPolicy by hand by doing:
threadTokenPolicy :: TTParams -> Scripts.MintingPolicy
threadTokenPolicy params = Scripts.mkMintingPolicyScript (
        $$(PlutusTx.compile [|| \x -> Scripts.wrapMintingPolicy @TTRedeemer (makeThreadTokenLogic x) ||])
        `PlutusTx.applyCode` PlutusTx.liftCode params
    )


---

