“reason”:”client request invalid: InvalidClientRequest(…)” Errors when writing to a Hyperledger Indy’s Ledger

Noha Abuaesh
4 min readFeb 24, 2021

Most of us developers know that, sometimes, error messages can be confusing. Indy is no exception.
To save you the hassle of it, I’m listing here the errors I faced when I tried to write to an Indy ledger for the first time, and how to solve them, with a brief explanation whenever I could.

A Ledger Photo by Sigmund on Unsplash — Just for fun.

Error 1 — “reason”:”client request invalid: InvalidClientRequest(‘validation error [SchemaField]: invalid number of parts 1, should contain 2 or 3 (version=1)’,)”

This error happened when I was trying to write a schema to the ledger.

“Versions must have at least 1 dot in them, but could contain as many as 2. The version string must look like a version, apparently. In other words, if your schema version was “1”, change it to “1.0” and that should do the trick. Well, at least it did the trick for me.

More about it: I looked for documentation to support it, but couldn’t find it. If it wasn’t for Lynn Bendixsen and Adam Burdett from Indicio Tech (A cool Indy implementation that offers you a free testnet and people like Lynn and Adam who are willing to help you out just because), this could’ve gotten the best of me — and the best of everyone who came here by googling this error!

Error 2— “reason”:”client request invalid: InvalidClientTaaAcceptanceError(‘Txn Author Agreement acceptance is required for ledger with id 1’,)”

Because writing to a ledger is permanent for life, you should sign a transaction author agreement every single time you want to write to an Indy ledger. And this is my implementation of it in python:

#####################################
async def add_taaAccept(request):
print(“ — — — — — — -TAA PROCEDURE — — — — — — — — — “)

# 1. Get Latest TAA from ledger
taa_request = await ledger.build_get_txn_author_agreement_request(issuer[‘did’], None)
latest_taa = await ledger.sign_and_submit_request(issuer[‘pool’], issuer[‘wallet’], issuer[‘did’], taa_request)
print(“Step A — TAA Retrieved “)

# 2. Get Acceptance Mechanisms List(AML)
acceptance_mechanism_request = await ledger.build_get_acceptance_mechanisms_request(issuer[‘did’], None, None)
aml = await ledger.sign_and_submit_request(issuer[‘pool’], issuer[‘wallet’], issuer[‘did’], acceptance_mechanism_request)
print(“Step B — AML Retrieved “)

# 3. Append acceptance to your request
latest_taa = json.loads(latest_taa)
taa_digest = latest_taa[‘result’][‘data’][‘digest’]
aml = json.loads(aml)
timestamp = aml[‘result’][‘txnTime’] # Getting the time from the AML tx
timestamp = int (timestamp/(60*60*24)) #Need to set timestamp to beginning of the day to reduce corratability risk
timestamp = timestamp*60*60*24 #return back to POSIX timestamp

# Values for Txn Author Agreement acceptance mechanism is one of:
# [‘at_submission’, ‘click_agreement’, ‘for_session’, ‘on_file’, ‘product_eula’, ‘service_agreement’, ‘wallet_agreement’]

request = await ledger.append_txn_author_agreement_acceptance_to_request(request, None, None, taa_digest, ‘at_submission’, timestamp)

request = await ledger.sign_and_submit_request(issuer[‘pool’], issuer[‘wallet’], issuer[‘did’], request)

print(“Step C — TAA Appended to your Request “)

print(“COMPLETED TAA PROCEDURE — — — — — — — — — — “)

# 4. Return appended request
return request
#####################################

So now, you just call this function before submitting a writing request to the ledger to get rid of this error.

Now this is something they added in 2019. Before the 2019 changes, you just had to accept the TAA once; when connecting to a pool, and that was it. So, you won’t find this extra step in the famous one-and-only Alice-Faber-Acme-Thrift example. You will only find that if you carefully read the documentation that was written after 2019 (or had someone like Lynn from Indicio Tech (A cool Indy implementation that offers you a free testnet and people like Lynn who are willing to help you out just because), to give you hints when you run into trouble.

More about it: I found these 2 links talking about the TAA updates:
https://github.com/hyperledger/indy-node/blob/master/docs/source/requests.md#transaction_author_agreement
and
https://github.com/hyperledger/indy-node/blob/master/docs/source/requests.md#common-write-request-structure

Error 3— “reason”:”client request invalid: InvalidClientTaaAcceptanceError(‘Txn Author Agreement acceptance time 1612822227 is too precise and is a privacy risk.’,)”

When appending the TAA acceptance to your request, the timestamp shouldn’t be the exact current time of accepting the TAA. The reason is the risk of getting to know who you are by following the pattern of you writing to the ledger. So, the timestamp should be the time of the start of the day of accepting the TAA. Check step 3 in the implementation above.

Sovrin documentation states: “Similarly, the application should not provide the time the user accepts, but only the day. Correlation risk can be further reduced by tracking a different acceptance date per DID on the ledger, or regularly asking the user to reaccept the agreement in order to change the acceptance date — although we acknowledge these approaches may increase the user’s friction when writing to the ledger.”

More about it: https://sovrin.org/preparing-for-the-sovrin-transaction-author-agreement/

Error 4 — “reason”:”client request invalid: UnauthorizedClientRequest(‘The action is forbidden’,)”

This basically means that you are trying to write some duplicate information to the ledger, for example, a schema/credential definition that already exists on the ledger with the same exact ID that.

To fix this error, you can just change the schema version(or credential definition name) you are trying to write to the ledger. Or, if you don’t need a new version, consider retrieving the old one from the ledger.

If you faced other problems, please leave a comment below about it, and I will add them to the list inshallah. Let’s try and make this easier for those who come after us!

--

--