Jun 10, 2026

Why VS Code Kept Using GitHub Copilot Quota Even After I Selected OpenAI Models

VS Code AI Setup

A practical troubleshooting note about VS Code Chat, Copilot quota, OpenAI models, utility models, and why "Auto" or "Vendor Default" can be misleading.

I recently ran into a confusing issue while using AI chat inside VS Code.

I had already reached my GitHub Copilot quota, so I wanted to use my own OpenAI API access instead. I selected OpenAI models in VS Code and expected the requests to stop using Copilot quota.

But I still kept seeing quota errors.

After checking the logs carefully, I found that the main model request was using OpenAI, but some hidden helper requests were still falling back to GitHub Copilot.

This article is my note for future reference, especially if I ever switch back to GitHub Copilot later.

The problem

The error looked something like this:

Sorry, your request failed. Please try again.

Reason: Response contained no choices.

At first, this looked like an OpenAI model response problem.

But the VS Code logs showed something more useful:

Server error: 402
You have exceeded your monthly quota
quotaExceeded | gpt-4o-mini

That means some request was still going through GitHub Copilot, even though I had already selected an OpenAI model elsewhere.

What was actually happening

My setup was not purely:

VS Code
→ OpenAI

It was more like:

VS Code Chat UI
→ Copilot Chat extension / VS Code chat wrapper
→ OpenAI model for the main answer
→ Copilot model for helper tasks

So the main chat response could succeed using OpenAI.

But VS Code still made extra helper requests for things like:

  • conversation title generation
  • utility tasks
  • context handling
  • summarization

Those helper requests were still using Copilot models.

The confusing part

The main OpenAI response could succeed, but a hidden Copilot helper request could fail because the Copilot quota was already exhausted.

Main OpenAI response = success
Hidden Copilot helper request = quota exceeded
Overall VS Code chat experience = unstable

The real trap: Auto / Vendor Default

Some VS Code settings were still set to:

Auto (Vendor Default)

or:

default

This sounds harmless, but it means:

Let VS Code or the active chat provider decide which model to use.

Because Copilot Chat was still part of the VS Code chat system, some background tasks continued to use Copilot models.

So even though I manually selected OpenAI for some visible model settings, hidden utility tasks still used Copilot.

The settings that fixed it

The important settings were:

chat.utilityModel
chat.utilitySmallModel

They were originally set to:

default

I changed both to an OpenAI mini model, for example:

chat.utilityModel = gpt-5.4-mini
chat.utilitySmallModel = gpt-5.4-mini
Result

After that, the logs stopped showing Copilot quota errors for title generation or utility tasks. Instead, I saw successful requests using OpenAI models.

Settings to check

If I want to avoid using GitHub Copilot quota, I should check these VS Code settings:

chat.utilityModel
chat.utilitySmallModel

Also check these model settings:

Chat Agent Default Model
Plan Agent Default Model
Edit Agent Default Model

Avoid leaving them as:

Auto (Vendor Default)
default

unless I intentionally want VS Code or Copilot to choose the model automatically.

My recommended setup

For my current workflow, I would use something like this:

Chat Agent: stronger OpenAI chat model
Plan Agent: Codex-style coding model
Edit Agent: Codex-style coding model
Utility Model: OpenAI mini model
Utility Small Model: OpenAI mini model

A more cost-conscious setup:

Chat Agent: OpenAI mini model
Plan Agent: Codex-style coding model
Edit Agent: Codex-style coding model
Utility Model: OpenAI mini model
Utility Small Model: OpenAI mini model

The key point is not the exact model name.

Do not leave utility models as default if Copilot quota is already exhausted.

How to read the logs

Some logs are mostly harmless:

Logged in
Got Copilot token
Public code references are enabled
Fetched model metadata

These do not automatically mean the request is using Copilot quota.

The important part is the actual model request result.

Good signs

success | OpenAI model name

Bad signs if Copilot quota is exhausted

quotaExceeded
gpt-4o-mini
You have exceeded your monthly quota
Failed to fetch conversation title

Different issue: OpenAI rate limit

Rate limit reached
tokens per min
TPM

This means OpenAI was actually being used, but the request was too large or too many tokens were used in a short time.

Copilot quota vs OpenAI rate limit

Issue Example log Meaning Possible fix
Copilot quota exceeded quotaExceeded | gpt-4o-mini Some request is still using GitHub Copilot quota. Change utility/helper models away from default/vendor default.
OpenAI rate limit Rate limit reached / TPM OpenAI is being used, but the request is too large or too frequent. Use fewer files, lower effort, smaller model, or split the task.

What "code-referencing" means

I also saw this log:

[code-referencing] Public code references are enabled.

This was not the cause of the quota problem.

It means Copilot can check whether generated code is similar to public code and show references when needed.

It does not mean my whole project is being uploaded or that this feature is consuming my OpenAI quota.

Effort setting guide

For AI coding tools, effort should not be based only on task size.

Higher uncertainty = higher effort
More execution volume = not necessarily higher effort
Effort Use it for
Low Small syntax fix, CSS change, add one CSP domain, rename variable.
Medium Normal coding task, inspect a few files, small refactor, add one feature.
High Multi-file refactor, unclear bug, architecture decision, security-sensitive change.
XHigh Large repo analysis, legacy migration planning, full documentation generation, unclear production issue.

For example, adding one missing domain to a CSP config usually does not need a very powerful model or very high effort.

But asking the agent to review the whole CSP strategy for a production app should use a stronger model and higher effort.

My rule for agent work

For large tasks, I should not use the highest effort for everything.

A better pattern:

XHigh = Think
High = Build
Medium = Verify

Example:

Discovery and planning: XHigh
Architecture plan: High or XHigh
Implementation: High
Small fixes: Medium
Testing and documentation update: Medium

This keeps cost and token usage under control.

Why I did not fully abandon Copilot Chat

At one point, I considered moving away from Copilot Chat completely.

But that would mean changing my existing VS Code workflow, including:

  • agent mode
  • file and folder references
  • MCP setup
  • custom instructions
  • tool permissions
  • workspace-aware chat habits

So the better solution was not to migrate immediately.

Keep the VS Code chat workflow.
Use OpenAI models explicitly.
Change hidden utility models away from Copilot defaults.
Avoid Auto / Vendor Default while Copilot quota is exhausted.

This allowed me to keep my current workflow while avoiding accidental Copilot quota usage.

Future revert guide

If I subscribe to Copilot again or get enough quota back, I can revert these settings:

chat.utilityModel = default
chat.utilitySmallModel = default

I can also set these back to:

Chat Agent Default Model = Auto (Vendor Default)
Plan Agent Default Model = Auto (Vendor Default)
Edit Agent Default Model = Auto (Vendor Default)

But I should only do this if I intentionally want Copilot or VS Code to manage model selection again.

If I want predictable OpenAI usage and billing, I should keep explicit OpenAI model choices.

Final lesson

The biggest lesson:

Do not trust Auto or Vendor Default when debugging quota issues.

Always check the logs and confirm which model actually handled the request.

The model selected in the UI may not be the only model being used. VS Code can also call helper models for title generation, summarization, utility tasks, and context handling.

If Copilot quota is exhausted, those helper calls can fail even when the main OpenAI model succeeds.

The fix was to explicitly set the utility models to OpenAI models instead of leaving them as default.

Mar 14, 2026

TEDUH Chrome Extension is back, and now it works in a much better way

Some time ago, I built a Chrome extension called Teduh Unit Counter to help property buyers browse TEDUH more conveniently. The earlier version has since been marked deprecated after TEDUH revamped its website and removed the old direct, URL-friendly experience.

In the old version, the extension depended heavily on the webpage UI itself. 

It needed the TEDUH page to load first, then it would read and extract the information shown on screen. That approach worked before, but it became much more fragile once the new TEDUH frontend was introduced.

What changed in the new version

The revived version now works in a very different way.

Instead of depending on the TEDUH webpage UI to expose the data, the extension now retrieves the information directly from TEDUH's server-side endpoints. This means the extension no longer needs to rely on opening a specific project page and scraping the rendered page content just to get the data.

From a technical point of view, this is a much stronger foundation than before.

Why this is better

  • Lookup is faster because the extension requests the data directly
  • It is less dependent on TEDUH's frontend layout and modal flow
  • The user experience is cleaner because data retrieval no longer depends on page rendering
  • The extension is now easier to maintain when the website UI changes again

What remains in real time

The project details and unit list are now retrieved live whenever a lookup is performed. In that sense, the extension now gives a real-time TEDUH lookup experience in a more direct way than before.

The trade-off

There is still a trade-off.

The old version was tightly coupled to the TEDUH webpage flow, so some page-specific observations were easier to derive directly from what was visibly loaded in the browser. The new version no longer depends on that rendered UI layer.

However, this does not mean newly sold tracking is completely gone. The extension still keeps track of newly sold units by comparing the latest fetched unit statuses with the previously saved local snapshot. So the feature still exists, but it is now based on local comparison logic rather than depending on the TEDUH webpage display itself.

Why I think this is the right direction

The old extension solved a real problem, but it was tied too closely to the website structure. Once the TEDUH frontend changed, the original approach naturally became outdated.

Rebuilding it around direct server-side data retrieval makes the extension more practical, more stable, and more future-resistant. It also makes the TEDUH experience much more convenient again for users who just want quick access to project information without clicking through multiple layers of UI.

Final note

So yes, the TEDUH Chrome extension is back.

This time, it is not just revived. It has been rebuilt on a better approach.

The previous version depended on the webpage. The new version talks to the data source more directly. That is the key difference, and it is exactly why the new version now comes back stronger than before.

Mar 6, 2026

My Experience Running MystNode on Phone, Computer, and Raspberry Pi

Do you know you can run MystNode from your phone or computer to contribute your idle internet connection and earn a little MYST with it?

I've been trying MystNode for quite a while - from Android phone, to the Chrome browser extension, until I finally settled on running it 24/7 with a Raspberry Pi.

From my experience, Raspberry Pi is the most convenient way to run it. I barely need to care about it, the device itself is cheap to keep on 24/7, and it's always there doing its job.

Running it on Android or computer feels more manual. Sometimes it goes offline for unknown reasons, possibly due to connection issues, and MystNode may turn itself off automatically. That means you need to check and reactivate it again.


Don't put too much expectation on how fast you can earn.

At first, I kept checking the earnings again and again until I eventually gave up, because the manual upkeep just didn't work well for me mentally. I had to be disciplined enough to keep it running properly. Switching to Raspberry Pi completely changed my view of the whole earning experience.

The earning rate is heavily geography-dependent. Nodes in countries with higher traffic demand naturally have more earning potential than those in lower-demand countries. So if you're running a node from a lower-demand country, it's better not to expect too much.

That said, I came back to it because of curiosity and experimentation. The journey wasn't very smooth, but I eventually understood better how it works, accepted the lower earning rate in my region, and honestly felt the experience itself was more valuable than the actual returns.

If you're curious, it's worth trying at least once.


MystNodes has also just released a new rewards system. From what I understand, you can now earn points in multiple ways, including by holding at least 100 MYST in your linked wallet. Running MystNode also contributes through uptime and shared internet traffic, so you may end up benefiting from more than one source at the same time.



I only found out about this new rewards system today, and since it was launched only a few days ago, I can't say yet how much the final result will be after one month. That part still needs time to see.

If you want to try it, here's my referral link:

https://mystnodes.co/?referral_code=9k0hY5CNpL13VRxicOmzMDR6ByK5AGT0TZhAHX6S

According to MystNodes, new users joining through a referral link can get a 5% bonus for one month from their MystNode earnings.

Enjoy earning with your spare internet traffic.

Feb 26, 2026

DevStorage - Chrome Webstore (simple quick tool for web dev)

DevStorage Is Live

Short announcement post

I am excited to share that my new Chrome extension, DevStorage, is officially live.

This started as a small side project. Not a startup idea. Not a big launch plan. Just a tool I built because I kept running into the same annoying workflow issue during local development.

If you have worked on modern web apps for a while, you probably know the feeling. You are testing authentication. You are toggling feature flags. You are simulating user states. And at some point, you end up deep inside Chrome DevTools trying to inspect or edit localStorage.

It works, technically. But it is not smooth.

You switch tabs. You open Application. You expand Storage. You scroll through keys. You copy and paste JSON. You clear everything when you only meant to delete one item. Then you start over.

After repeating that cycle enough times, I decided to fix it for myself. That is how DevStorage was born.

Chrome Web Store listing: DevStorage

What DevStorage does

DevStorage is a lightweight Chrome extension that makes working with localStorage faster and less frustrating.

It lets you view keys clearly, edit values quickly, remove specific entries without wiping everything, and clean up storage without digging through DevTools every time.

The goal was simple: reduce friction.

I did not want to replace DevTools. I just wanted something that feels more direct when you are in the middle of debugging and need to adjust storage quickly.

When we are building SPAs, storage becomes part of the debugging loop. Tokens live there. Feature flags live there. Temporary state lives there. Having fast access to that data saves time, especially when you are jumping between environments or testing edge cases.

Why I decided to ship it publicly

Originally, this was just a small internal helper. I built it to make my own workflow cleaner.

But after using it for a while, a teammate asked how I was managing storage so quickly. That is when I realized it might actually help other developers too.

Shipping it publicly forced me to polish things properly. Clean up the UI. Double-check permissions. Make sure performance stayed tight. Write clearer descriptions. Remove things that only made sense to me.

That process alone was valuable. It reminded me that even small tools deserve thoughtful design.

What I focused on while building it

I kept the scope intentionally narrow.

The first version does one thing well: it gives developers clean, fast control over localStorage.

I avoided adding too many features. No analytics. No cloud sync. No complicated dashboards. Just a focused interface that shows your storage clearly and lets you manage it without noise.

One thing I learned is that simplicity takes effort. My early versions had more buttons and more UI states. It looked powerful, but it felt heavy.

So I asked myself a basic question: what do I actually use every day? Anything that did not serve that answer got removed. That decision made the extension better.

What building this taught me

Even though this is a relatively small extension, it reinforced a few lessons for me.

Chrome extension architecture matters more than you think. Understanding permissions, background scripts, and storage APIs early saved me from messy refactors later.

UI clarity is harder than writing logic. The functionality worked early on. Making it intuitive took longer.

And most importantly, developer tools should feel invisible. When you click the extension icon, you should not have to think. You should just see what you need and move on.

That was the benchmark I kept testing against.

Who this is for

DevStorage is useful if you regularly work with localStorage during development.

If you debug login flows, test feature flags, simulate user states, or often need to reset specific keys without clearing everything, this will probably save you time.

If you rarely touch browser storage, you might not need it. And that is fine. I would rather build something focused that genuinely helps a specific group of developers than something broad and generic.

What is next

Now that it is live, the real work begins.

I am paying attention to feedback and watching how people actually use it. There are ideas I am considering, like adding search, supporting sessionStorage, or allowing export and import of storage snapshots.

But I do not want to guess what developers need. I would rather improve it based on real workflows.

If something feels awkward or unnecessary, that is exactly the kind of feedback I want.

Final thoughts

DevStorage started as a small fix for a daily annoyance. It turned into a public Chrome extension that I am genuinely proud of.

It solves a real problem in my workflow. That alone makes it worth building.

If you spend time debugging browser storage, give it a try. And if you are building small tools of your own, I would encourage you to ship them. You do not need a huge idea to create something useful. Sometimes removing a tiny bit of friction is enough.

If you try DevStorage, let me know what you think. I am always open to improving it.

Feb 3, 2026

Simple systems just survive longer

Why simple systems survive longer

Simple systems tend to last because they're easier to maintain, explain, test, and recover. Complexity can create short-term speed, but simplicity builds long-term trust.

  • When a system grows, break it into smaller chunks (modules/services) so changes stay local and safer.
  • Give each chunk a single purpose and clear boundaries, so it can be understood and evolved independently. (Not "isolated forever" - just intentionally scoped.)
  • Keeping chunks small and maintainable is one of the most reliable strategies in system design - not a universal law, but a principle that keeps paying rent.

Keep it small. Keep it clear. Keep it alive.