We stored 'no expiry' and 'never checked' in the same blank field
October 6, 2026 · Taro — Founder, KAZENA
On 1 October I counted the values our software stores in order to connect to outside services. There were 11. For 8 of them we could not say when they had been created. What started the counting was a notice that had arrived 2 weeks earlier.
The notice came on 16 September. One of the services we connect to is ending tokens that never expire; from now on they are replaced by tokens that run out after 60 days. When I read it, I thought I understood what had to be done. Issue a new token, then build a procedure to swap it every 60 days. It looked small as a piece of work, so I marked it to read later and closed it.
The reason I put it off was probably in the word I used. In my head I called this a renewal job. A renewal is a procedure, and a procedure can wait until there is a free afternoon. In fact it was not a procedure. It was a notice that an assumption we had left untouched for more than 2 years had been withdrawn from the outside.
On 1 October I started the work and stopped at the first question. When was the token we are using now created? I searched our own records and found a single line in a setup document: paste the value here. No date. In the end I opened the provider's console to find out. It was more than 2 years old. In those 2 years, our code had never once asked that value how old it was.
So I looked at the rest the same way. Here is what the 11 break down into. The provider sets an expiry on 4 of them and sets none on 7. Of the 4 with an expiry, we had recorded the creation date for exactly 1. For the others, the only way to know is to open a console or ask the person who created it.
While counting I found 1 that had already expired. Not a production value, but one used by a test connection. It had run out in late July. We had not noticed because the check that uses it was built so that a failure does not say failure. When authentication fails, that check is skipped and the run as a whole still reports success. For more than 2 months, that check had been passing without checking anything.
Something came back to me. In August, E wrote to say a test notification had not arrived. He has been with us since the founding; he is in a small town some way outside Jakarta, and he has looked after real-device testing and local delivery from the start. We resent the message through the production path, it reached his phone, and we closed the matter there. What arrived came through a different path. Nobody asked why the other one had not.
Here is the part that mattered most this time. Inside our data, the provider sets no expiry and we have not checked the expiry were stored as exactly the same blank field. Neither holds a value, so they cannot be told apart. One of them is a statement by the provider; the other is an admission that we do not know. Opposite meanings, saved in the same shape.
Lasting forever was never a property we owned either. It is a promise the other side keeps, and a promise can be ended whenever it suits them. A token with no expiry does not lack an expiry; its expiry has simply not been decided yet. Seen that way, the notice was not an accident. It is an ordinary thing that happens.
Three things we changed. First, every value we store now carries the date it was created, the date it expires and where it was created. When the provider sets no expiry, we write none set rather than leaving it blank. That way only the ones we have not looked at stay blank, and whoever reads it later can count how many we still owe.
Second, the days remaining are now shown where a person looks. When fewer than 14 days are left, a line appears at the top of the settings screen. But the settings screen is not something we open daily. A warning placed where nobody looks is the same as no warning, so the same line also goes into the check email that reaches us every morning.
Third, we stopped treating an authentication failure as something that may be skipped. Even on a test connection, when we cannot get in we now say we could not get in. The build that silently passes what did not pass was meant kindly when we wrote it. I think we were trying not to get in the way of whoever was running it. What it actually did was throw away 2 months of checks without a word.
The same error of thinking was in a screen our customers see. After a connection to an outside service is made, we showed only the word connected. We wrote it as a report of something that had happened, but people read it as a statement about the future. Now we show the date the connection was last confirmed alongside it, and when an expiry is known, that date too. It is longer to read than connected, but it lets the person decide when it is worth checking again.
One last thing to ask. If there is anything on a KAZENA screen where you cannot tell what point in time it refers to, please tell us. A screen that says only done is usually a place where we left out the date on which we checked.
Tell us what you think
How the KAZENA apps feel to use, what we should fix, features you wish existed — if you run a small or medium business or work freelance in Indonesia or the Philippines, your voice is exactly what we want to hear. Messages in Bahasa Indonesia or English are answered by teammates who know your market from the inside. KAZENA Books is already set to launch in the Philippines and Indonesia — and if your company would like to bring it to other countries as a partner, or is interested in acquiring the system, we would love to hear from you too. We also take on new system development. We are a small team, so we cannot always start right away — but what we build carries made-in-Japan quality and stays close to how business really works here, one project at a time.
Get in touchMore from the blog
Cash went up but the month was in the red — why that happens
October 23, 2026 · Taro — Founder, KAZENA
Was last month profitable? Find out with 1 subtraction a month
October 18, 2026 · Taro — Founder, KAZENA
Keep the shop's money somewhere other than your own wallet
October 15, 2026 · Taro — Founder, KAZENA
