Skip to content

Vibe Log #3: Debugging django with Qwen3.6

Another day, another back to back model drop from our friendly neighborhood frontier tech orgs.

HN screenshot

The darling is Qwen3.6. Open source, 3B active MoE, and a pelican at the level of a 5T parameter model. Let's give it a go.

ollama run claude --model qwen3.6

The case of the disappearing input value

We've got a simple problem today. A task I might give an intern or jr. eng on day 1 as an excuse to explore the source code with low stakes.

Disappearing DQL

Simple, but an infuriating problem nonetheless, as anyone who's had to re-enter their credit card number after an accidental page refresh can attest.

❯ In DQL search, some wrong DQL queries disappear from the search box after hitting “Search”. This one for example: 

type:Person employments.location.country.name:"Italy" employments.{isCurrent:true HAS:location.country NOT(location.country.name:"Italy")}) 

(added one round bracket in the end). Fix this issue so that wrong DQL queries that error will still hold onto their values in the DQL input field.

As expected, it started by finding its bearings through the source code. Not a whole lot has been written into the shared CLAUDE.md at this time, so it's flying quite blind.

I offer a hint.

❯ I'm referring to diffbot_dashboard.views.search.

Just a nudge in the right direction so it won't burn itself out.

qwen3.6 spun its wheels for a time, then made some edits.

● The fix is a one-liner. Here's what was happening:

  Root cause: When the DQL query fails validation, the view sets processed_form['error'] = True and returns the bound form in context (dql_form), but never sets search_query. The textarea at line 221 used {{ search_query }} which evaluates to nothing, clearing the input.

  Fix: Changed {{ search_query }} to {{ search_query|default:dql_form.query.value }} — Django's bound form field value always contains the original submitted value, so it falls back correctly when the form has errors.

This fixed the issue, but now the DQL field starts with "None" by default (rather than being blank).

Not the best start. I tell Claude-qwen3.6 this, which then proceeded to explain the root problem and the same suggested fixes 3 times in a row.

Qwen suggesting the same fix 3 times in a row

Your Majesty, qwen3.6 is exhausted because only qwen3.6 can take THIS and THIS and GIVE YOUUU

Qwen's looped result

What a beautiful monstrosity.

Thankfully, qwen caught on to this.

● That's too complex. Let me simplify the template. The cleanest approach is to ensure initial_query is always set and use it directly.

qwen3.6 took off after this stroke of insight. It followed the logic flow, checked for scope, and cleaned up unnecessary prior code changes. 14 minutes later, it has reverted everything it has written.

❯ We're back to the original problem again. An error will return an empty input field value.

Somehow, it did manage to arrive at the real root problem after this turn.

● I see the issue now. When the user enters a malformed DQL query, Django's form validation (is_valid()) passes because the field is non-empty. The API call later rejects it, which sets a Django messages.error() (not form errors). In that code path (processed_form['error'] is False), search_query is never set in context.

The final fix is 2 lines, both defining search_query for the context on two possible error states.

Stats

Token usage stats

  • Days Working on Task: 1 (~28 minutes token burning time, ~1 hour of my time)
  • AI Dev Evolution Stage: 2
  • Total Input Tokens: 8,040,008
  • Total Output tokens: 57,926
  • Total Tokens (including cache): 8,097,934 (no cache logged)
  • Total API Cost: $0.00 (running locally on a DGX Spark)

Stats from ccusage

Notes

8M feels like a lot of tokens for this level of problem. But when each token is $0.00 it's hard to complain.

Is it Opus? Absolutely not. I wasn't expecting anything close. Yet here we are, a local model running on my desk pushing deploy-ready hot fix MRs to production with minor supervision. Zero probably, if I gave it headless Chrome to play with, or otherwise avoided prompting frontend tasks.

Where heavyweight models are starting to feel measured in ability, lightweight models are still continuing to make big leaps — smaller, faster, smarter.

See you on Vibe Log #4!