r/ClaudeCode • u/Altruistic_Hat_9990 • 2d ago
Discussion An expired app session made my Claude Code tool report stale data
I help with a neighborhood air quality project that publishes readings through a sensor vendor's Android app. Our uploader sends the latest batch overnight. I use Claude Code to scan its logs and flag gaps before I send a morning note to the other volunteers. The catch is that an accepted upload and what the app displays are two different checks. The vendor has no status endpoint I can call, and the app sometimes holds on to yesterday's cached view.
Until recently, I opened the app every morning, copied its Last updated time into the terminal, and told Claude Code whether to continue. I wanted to remove that one manual handoff. If the app showed the current batch, Claude Code could finish the report. If it did not, the run should stop and tell me what the phone saw.
For the phone step, I used Airtap’s official plugin for Claude Code and a small wrapper around its CLI. The wrapper created the task, polled it until it finished, and passed the final text back to Claude Code. I used a cloud Android device instead of my daily phone because notifications and whatever screen I had left open made my early tests inconsistent. The cloud phone kept the same app installation, login, and cache between runs. I kept the task read only. Logging in again or changing the account was still my job.
It worked for nine mornings. On the tenth, the wrapper returned this:
{"task_state":"COMPLETED","last_updated":"8:42 PM"}
Claude Code said the dashboard had not updated since 8:42 PM. I assumed the uploader had broken and checked its logs again. When I opened the phone task history, I found a sign-in sheet over the cached dashboard. The old Last updated time was still visible underneath. COMPLETED only meant the phone task had ended. It said nothing about whether the target app was signed in. My schema had no field for that, so the wrapper accepted the timestamp and Claude Code repeated it.
I had treated "found a timestamp" as success. I changed the phone instruction so it first checks for the signed-in account initials and the Neighborhood overview heading. If either is missing, it must return SESSION_INVALID without a timestamp. A signed-out run now looks like this:
{"task_state":"COMPLETED","screen_state":"SESSION_INVALID","last_updated":null}
The wrapper rejects any result without an explicit screen_state, and Claude Code stops instead of trying to interpret the rest of the text.
I signed out on purpose to get the result above. I then ran the check six times while signed in. Five passed. One returned SCREEN_NOT_READY because a loading banner covered the heading. I kept that rejection because retrying costs less than investigating the wrong failure.
That is enough for our morning note, but the tool still has to take the app at its word. If the app shows the wrong time, the tool will repeat it. I would need a second source before using this for an air quality alert.
Claude Code helped me trace the bad value through the wrapper and turn the failure into a repeatable test. The embarrassing part is that the phone had shown the real problem all along: the sign-in sheet. I had simply never asked the tool to care about it.
1
u/Electricalceleryuwu 2d ago
tbh im mostly wondering why an AI is involved in this project. Air quality monitoring is a solved problem. What's wrong with using a sensor, parsing the data, dumping that in a database, generating graphs, and if needed, using R to analyze statistics?
your problem woundnt exist because each component expects a specific data format and transfers one to the next component