1

I wrote a Solana Program with two functions, one for the initialization of an account and a second to upload data to the account. While testing on localhost it was working fine, but when I uploaded it to Devnet I get the following error:

Error: AnchorError: AnchorError caused by account: base_account. Error Code: AccountNotInitialized. Error Number: 3012. Error Message: The program expected this account to be already initialized.
      at AnchorError.parse (C:\Development\SmartHealth\smarthealth_js\node_modules\@project-serum\anchor\dist\cjs\error.js:138:20)
      at translateError (C:\Development\SmartHealth\smarthealth_js\node_modules\@project-serum\anchor\dist\cjs\error.js:224:37)
      at Object.rpc [as uploadRecord] (C:\Development\SmartHealth\smarthealth_js\node_modules\@project-serum\anchor\dist\cjs\program\namespace\rpc.js:18:53)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async uploadToSolana (file:///C:/Development/SmartHealth/smarthealth_js/index.js:69:22)
      at async file:///C:/Development/SmartHealth/smarthealth_js/index.js:131:28

The error comes up only when I try to upload the data and sometimes it doesn't come up at all and the data gets uploaded successfully to the account. I am not sure why I am getting this error sometimes. Can someone please tell me what is the problem?

Below is the JS code through which I am calling the Solana program functions:

const tx = await program.rpc.initialize({
        accounts:{
            baseAccount: baseAccount.publicKey,
            user:provider.wallet.publicKey,
            systemProgram: SystemProgram.programId,
        },
        signers: [baseAccount]
    }).catch((err)=>{
        console.log(err)
        return {"Error":err}
    });

console.log('New Base Account Generated: ',baseAccount.publicKey.toString());
console.log("Transaction Signature: ",tx);

const timestamp = new Date().toUTCString()
    const uploadTx = await program.rpc.uploadRecord(pid,did,title,file_id,timestamp,{
        accounts: {
            baseAccount: baseAccount.publicKey,
            user:provider.wallet.publicKey,
        },
    }).catch((err)=>{
        console.log(err)
        return {"Error":err}
    });

I have even tried keeping the pid,did, title,file_id values the same but still I get the error sometimes. Even the account gets generated as I get the transaction signature for that on the console but data doesn't get uploaded.

2
  • Can you add more context by sharing the program this error means that you are trying to use an account that has not been created yet
    – Pratik.js
    Commented Feb 27, 2023 at 12:50
  • @Pratik.js Hey, Thank You but actually the code started working after I put a delay between the initialization and upload function calls Commented Feb 27, 2023 at 17:44

1 Answer 1

2

Instead of running these one after the other or adding a delay between them, but both instructions into the same transaction. E.g.:

  let tx = new Transaction();
  tx.add(await program.methods.initialize(....).instruction());
  tx.add(await program.methods.uploadRecord(....).instruction());
  await program.provider.sendAndConfirm(tx, [baseAccount]);

This way the account is always created when you go to call upload, because it will be created earlier within the same tx.

4
  • I changed my code to the way you said but I get the following error: throw new Error(provided too many arguments ${args} to instruction ${idlIx === null || idlIx === void 0 ? void 0 : idlIx.name} expecting: ${(_b = (_a = idlIx.args) === null || _a === void 0 ? void 0 : _a.map((a) => a.name)) !== null && _b !== void 0 ? _b : []}); ^ Error: provided too many arguments [object Object],[object Object] to instruction initialize expecting: at splitArgsAndCtx Commented Feb 28, 2023 at 4:52
  • Code: let tx = new Transaction(); tx.add(await program.methods.initialize({ accounts:{ baseAccount: baseAccount.publicKey, user:provider.wallet.publicKey, systemProgram: SystemProgram.programId, } }).instruction()); tx.add(await program.methods.uploadRecord(pid,did,title,file_id,timestamp,{ accounts: { baseAccount: baseAccount.publicKey, user:provider.wallet.publicKey, } }).instruction()); await program.provider.sendAndConfirm(tx, [baseAccount]); Commented Feb 28, 2023 at 4:52
  • Replace the .... in each methods.whatever with your instruction args. E.g. methods.initialize(ARG1, ARG2, ARG2).accounts({someacc: whatever})
    – Whiteseal
    Commented Mar 1, 2023 at 0:01
  • Yeah I was doing it wrong, Thank You, it worked Commented Mar 1, 2023 at 5:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.