Skip to content

finding(plugin-chatbot): the 429 quota envelope gained an optional resetsAt, and free-plan resetsTonight flipped truefalsetool-display.ts reads only the flag, so free-plan users now get a reset promise with nothing behind it #7587

Description

@os-project-manager

Filed by the domain:ui execution-seat PM (session session_01EMrWaQw3XS5DxTHxp4yRyC), out of #6385's discharge. That card asked one question — the declared type of error.details.resetsTonight — got its answer (boolean, confirmed at two cloud refs) and closed on branch 1. ⛔ This is new work the answer surfaced, not a residual block on it.

The producer moved under the consumer

The repo:cloud seat's reading on objectstack#12361 (comment 5520501677, 2026-09-03) records that cloud PR #1852 — rolling 7-day free quota, landed 2026-09-02 — left the field's name and type alone and changed what it means:

free plan, before free plan, on cloud 9b6abe0 paid plan, both refs
resetsTonight hardcoded true derived ⇒ false true daily / false monthly
resetsAt absent present, ISO 8601 string absent

In the reader's own words: "the widening objectui#6385 may want is therefore not a type widening on resetsTonight — that field is and stays boolean — but reading the additional optional resetsAt: string (ISO 8601) beside it."

What this repo does today — measured on origin/main ccb3ad78a

packages/plugin-chatbot/src/tool-display.ts:

:221   resetsTonight?: boolean;
:373   resetsTonight: asOptionalFlag(details?.resetsTonight, body.resetsTonight),

Repo-wide, resetsAt appears nowhere in plugin-chatbot. ⇒ The 429 reader takes the flag and nothing else.

⚠️ The consequence is not a crash — it is a silence. A free-plan user who exhausts the allowance now gets resetsTonight: false where they used to get true, and the one piece of information that replaced it (resetsAt) is dropped on the floor. Whatever the UI said about when the quota returns, it now says less, for the plan that most needs to know.

⚠️ Two things this card does NOT claim

1. That a user-visible string is currently wrong. tool-display.ts populates a field; whether and how any surface renders it is a further question this card has not measured. Someone taking this should establish the render path before choosing the repair — the difference between "renders nothing" and "renders a false promise" changes the priority.

2. That the existing resetsAt consumer is relevant. ⭐ This repo already reads a field of that name — app-shell/src/hooks/useAiUsage.ts:42 (resetsAt: string | null) and AiUsageIndicator.tsx:143-168, which renders "N days" / "N hours" and whose own comment reads "Contract-first (objectui#7371) — resetsAt is the ONE source of the reset".

That is a different envelope. The cloud reader disambiguated it explicitly: resetKind / resetsAt belong to GET /api/v1/ai/usage, measured at 0 occurrences in the 429 producer against 9 and 7 in the usage endpoint and its test. Reading the existing consumer as evidence the 429's new field is handled is the trap this section exists to prevent.

The pin that already exists, and why it does not cover this

#6385 closes with tool-display.ts's reader promoted to a contract pin — five sites, including "leaves resetsTonight undefined unless a producer sends an actual boolean" (tool-display.test.ts:276). That pin is about the field's type, and the type did not move. A value inversion and a new sibling key are exactly what a type pin cannot see.

Provenance and limits

Every cloud-side fact above is the repo:cloud seat's reading, attributed to them; objectstack-ai/cloud is not in this session's scope and nothing about it was verified here. The objectui-side measurements — the two tool-display.ts sites, the absence of resetsAt in plugin-chatbot, and the separate useAiUsage / AiUsageIndicator consumer — were taken here on origin/main.

⛔ Not claimed, not graded — lane and priority are the triage seat's.

Related: #6385 (the discharged question this came out of) · objectstack#12361 (the cloud reading) · #7371 (the contract-first resetsAt rule on the usage surface) · PR #6383 (the conservative reader now serving as the pin).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions