DEV Community

Cover image for Soul in Motion — 10:09 AM | 2026-09-29
Dev Rajput
Dev Rajput

Posted on

Soul in Motion — 10:09 AM | 2026-09-29

TL;DR

  • A stubborn button click bug was traced across the frontend‑backend boundary in ~3 hrs.
  • Built a data‑labeling ↔ ML platform pipeline using custom scripts; got two incompatible systems to talk.
  • Balanced heavy debugging with AI‑assisted quick fixes and scheduled breaks (binge‑watching Scorpion).
  • Ended the day with a working UI, a functional pipeline, and a refreshed mind.

The “Trivial” Bug That Took 3 Hours

I started 10:09 AM with a button that did nothing.

The click event fired in the browser, but the expected API call never reached the server.

That’s the classic “between‑the‑layers” problem: the frontend sends a request, the backend never receives it.

Tracing the Signal

  1. Console logs – added console.log('clicked') in the click handler.
  2. Network tab – verified the request was sent, but the URL was /api/unknown.
  3. Router check – the route /api/unknown didn’t exist.
  4. State inspection – the component’s state was null when the handler ran.
  5. Prop drilling – the handler was passed down from a parent that never updated its state.

The culprit: a missing useEffect that should have fetched the endpoint URL from the config.

After adding:

useEffect(() => {
  fetch('/config')
    .then(r => r.json())
    .then(c => setApiUrl(c.buttonEndpoint));
}, []);
Enter fullscreen mode Exit fullscreen mode

the button finally hit /api/submit. The triumph of seeing that last line of code land correctly after hours of dead ends is quiet but real.


Building a Clean Pipeline Between Labeling and ML

The next task was to wire a data‑labeling framework (LabelStudio) with an ML platform (MLflow). They speak different protocols: LabelStudio exposes a REST API, MLflow expects a gRPC endpoint for model training.

The Script

I wrote a lightweight Python orchestrator that:

  1. Pulls labeled data from LabelStudio via its REST API.
  2. Converts the JSON annotations into the CSV format MLflow expects.
  3. Calls MLflow’s run API to trigger training.
import requests
import csv
import mlflow

# 1. Pull labels
labels = requests.get('https://labelstudio.example.com/api/v1/projects/42/data').json()

# 2. Convert
with open('train.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['image', 'label'])
    for item in labels:
        writer.writerow([item['image_url'], item['label']])

# 3. Trigger MLflow
mlflow.set_tracking_uri("http://mlflow.example.com")
mlflow.run(
    uri="models/ResNet50",
    entry_point="train",
    parameters={"data_path": "train.csv"}
)
Enter fullscreen mode Exit fullscreen mode

The script was fiddly—handling pagination, rate limits, and ensuring the CSV schema matched the MLflow model’s expectations—but once it ran, the two systems spoke the same language.


Balancing Work, AI Assistance, and Breaks

I didn’t let the day get too long. After the button fix, I scheduled a 30‑minute break to binge‑watch Scorpion. Each episode ended on a cliffhanger, pulling me straight into the next. Between those breaks I:

  • Used ChatGPT to generate quick snippets for error handling.
  • Ran curl commands to test endpoints while the browser was idle.
  • Sketched a diagram of the data flow in a whiteboard app.

The AI assistance was a speed‑up, not a replacement. I still had to review the generated code, but it cut the time on trivial questions from minutes to seconds.


Wrap‑Up

By 5 PM:

  • The button worked reliably.
  • LabelStudio and MLflow were integrated via a clean pipeline.
  • I had watched enough Scorpion to feel my brain had actually rested.

Not every day needs a dramatic arc. Sometimes it’s just a stubborn bug, a useful integration, and a season finale getting closer. Tomorrow’s already lined up—stay tuned for more.


Top comments (0)