Skip to content

Fixing Data

String Theory is a strictly immutable ledgering system. That means you can’t delete any data. A common question we get is “What if something is a mistake, how do we fix it?”. This section outlines the common scenarios you might find yourself in and ways to approach them.

Keep in mind, there are no one-size-fits-all solutions here. When choosing which of these paths to use, its important to consider the context of what happened, and also what your desired end-state will be.

  • Dropped messages in infrastructure
  • Missing integration points in your system
  • Code bug, or manual error reducing the amount of an intended deposit

The solution here is fairly straightforward, you can make a new deposit to compensate for the amount that is missing.

Note: If this issue is due to deposit calls to String Theory not going through, make sure to use the idempotency key from the original request to avoid any possible duplicates.

Diagram: Deposit to make up for missing money

  • Extra deposits were mistakenly made
  • Vague or non-deterministic idempotency keys resulted in duplicate deposits
  • Code bug, or manual error increasing the amount of a deposit

The solution is to use the withdraw operation to remove the excess money from the system.

Note: String Theory’s ability to uniquely identify money is really useful when solving issues like this. We strongly suggest targeting the exact pieces of money by id when taking corrective actions like this.

Diagram: Withdraw to remove excess money

An Extra Loan Was Made, but the Money Hasn’t Been Used

Section titled “An Extra Loan Was Made, but the Money Hasn’t Been Used”
  • A loan was made erroneously, but the money has not been used .
  • Vague or non-deterministic idempotency keys resulted in duplicate loans
  • Code bug, or manual error believing a loan was needed

Use the repay operation to return the loan to the lender.

Note: It’s important to use repay to ensure the both the positive money and debt associated with the loan is handled appropriately. While you could do the individual deposits and withdrawals by hand, it is not recommended for this simple case.

Diagram: Fix an extra loan where the money hasn't been used

An Extra Loan Was Made, and the Money Was Spent

Section titled “An Extra Loan Was Made, and the Money Was Spent”
  • A loan was made erroneously, and then we spent the positive amount.
  • Vague or non-deterministic idempotency keys resulted in duplicate loans
  • Code bug, or manual error believing a loan was needed
  • A well intentioned process spent the loan money, because it hadn’t been marked as in error yet

The solution here depends on the business outcome that you want. In this case, we incorrectly loaned money to someone, and then our system allowed that money to be paid out. The current state of the system is as follows:

  • The positive money from the loan is gone
  • The debt from the loan remains

Since there is recorded debt for the money that was erroneously spent, if you intend to recoup that money from the person it was lent to, you don’t need to do anything to the ledger as it correctly reflects the debt associated with the loan that was made. Make sure to use your normal business processes for handling debt to ensure you get paid back.

If you do not intend to recoup the money, then you should “write off” the debt associated with the loan using the withdraw debt operation.

Note: If the loan was partially spent, use a combination of repay from the last section, and withdraw debt to get to the desired end state.

Diagram: Fix an extra loan where the money hasn't been used
Diagram: Write off bad debt for an erroneous loan

  • A withdrawal (or series of withdrawals) was made for an amount greater than intended.
  • The source has enough money to cover the bad withdrawal(s).
  • Vague or non-deterministic idempotency keys resulted in duplicate withdrawals
  • Code bug, or manual error increasing the amount of the withdrawal

The solution here depends on the business outcome that you want. If you intend to try to recoup the money from where we sent the incorrect withdrawals, then no action is immediately needed. Use the return operation to return the withdrawals once you’ve confirmed that you got the money back.

If, instead, you intend to reimburse the person for the incorrect withdrawal with your own money, then you should use a transfer from your operational account to the impacted account.

Note: When correcting this state it is important not to use a loan when you do not intend to get the money back. However, it would be appropriate to loan if you intend to try to recoup the money, but want to temporarily make the impacted person whole.

Diagram: Return money from an erroneous withdrawal
Diagram: Transfer money from an erroneous withdrawal

Money Was Spent, but the Source Didn’t Have Enough Money

Section titled “Money Was Spent, but the Source Didn’t Have Enough Money”

This can’t happen in String Theory. It will not allow withdrawals of money that does not exist. The only way to get into this scenario would be to loan money, and if your system did that refer to the sections on handling erroneous loans.


Money Was Deposited, but Later It Was Discovered That It Was An Error (Money Was Not Spent)

Section titled “Money Was Deposited, but Later It Was Discovered That It Was An Error (Money Was Not Spent)”
  • A deposit was recorded in the system, but later it was discovered that the money was never actually received.
  • The system did not spend the erroneous money, and its still available in the system
  • Code bug, or manual error in making the deposit
  • Integrations with 3rd party payments or money movement systems (these routinely make mistakes as part of normal ops)
  • A charge back was done after the initial recording

Since the money was not spent, you can use the withdraw operation to remove the offending money.

Diagram: Fix a deposit where the money wasn't spent

Money Was Deposited, but Later It Was Discovered That It Was An Error (Money Was Spent)

Section titled “Money Was Deposited, but Later It Was Discovered That It Was An Error (Money Was Spent)”
  • A deposit was recorded in the system, but later it was discovered that the money was never actually received.
  • The system spent the money, because it believed in good faith that you had it, but it was later discovered that you never received it (or it was charged back).
  • Code bug, or manual error in making the deposit
  • Integrations with 3rd party payments or money movement systems (these routinely make mistakes as part of normal ops)
  • A charge back was done after the initial recording

This means that your system spent money in good faith, but you found out later you never actually had it. This is really a worst case scenario, and you should do everything possible from the business perspective to minimize this behavior. However, particularly when integrating with 3rd party systems, this can happen through no fault of your code or your system.

How you handle this depends on the business outcome you want. If you intend to recoup the money from the impacted user (in the case of a charge back, for example) you should use the loan operation to create debt equal to the amount withdrawn.

If you do not intend to recover the money, you have several options. The end state is that you need to recognize that this money came from your accounts, and not the recorded one. These are some options:

  1. [preferred] Mark the withdrawal as an error (using tags, or metadata), and use a hold to freeze it. Then transfer money from your operations account, and withdraw it to show what really happened. Which is that you paid for that withdraw out of your own pocket, even though you didn’t think you were doing that at the time. If you intend to recoup the money, deposit debt equal to the amount withdrawn.

  2. Directly withdraw the amount from your operational account, but do not change any meaningful information about the original withdrawal (just add metadata). This has fewer steps, but is far more vague. It may be difficult to attribute this money correctly to the initial bad withdraw. Additionally, it doesn’t reflect well what actually happened, and String Theory always suggests modeling your ledger as close as you can to the actual events that took place.

Diagram: Fix a deposit where the money was spent
Diagram: Fix a deposit where the money was spent
Diagram: Fix a deposit where the money was spent