Skip to content

mmx quota show reports 100% remaining for video, but mmx video generate rejects with 0/0 used #173

@hongruiji

Description

@hongruiji

Bug: mmx quota show reports "100% remaining" for video, but mmx video generate rejects with (0/0 used) — quota endpoint and generation endpoint give contradictory data

Summary

mmx quota show (text and JSON mode) reports 100% remaining for the video model on a Token Plan Plus plan. mmx video generate against the same API key, in the same session, is rejected with usage limit exceeded, weekly usage limit reached for Token Plan Plus (0/0 used). The two endpoints — /v1/token_plan/remains (quota show) and /v1/video_generation (generate) — return semantically contradictory data, so the CLI ends up confidently telling the user "you have 100% video quota" and then immediately refusing the request. There is no plan that lets the user discover the 0/0 allowance from the quota screen.

This is a follow-up to #165 (closed in v1.0.16). That fix made the panel render the percent / time fields correctly, but it surfaced — and is now load-bearing on — a server-side inconsistency: current_interval_remaining_percent: 100 is being returned for a model whose weekly allowance is literally 0.

Environment

  • mmx-cli 1.0.16 (mmx --version)
  • Node 18+ (running on macOS)
  • Auth: API key (mmx auth statusapi-key)
  • Region: cn (base url https://api.minimaxi.com)
  • Plan: Token Plan Plus

Steps to reproduce

  1. mmx auth login --api-key sk-... with a Token Plan Plus key.
  2. mmx quota show — observe the video row says 100% remaining, 100% weekly remaining, "resets in 6h 42m".
  3. mmx video generate --first-frame 1.png --prompt "..." --download out.mp4 — the call is rejected.
  4. (Optional) Re-run the same call as a direct curl against /v1/video_generation with duration: 10, resolution: "768P" to bypass any CLI serialization.

Actual output

mmx quota show --output json (relevant row, model_name: "video")

{
  "model_name": "video",
  "start_time": 1780848000000,
  "end_time": 1780934400000,
  "remains_time": 23965834,
  "current_interval_total_count": 0,
  "current_interval_usage_count": 0,
  "current_weekly_total_count": 0,
  "current_weekly_usage_count": 0,
  "current_interval_status": 3,
  "current_weekly_status": 3,
  "current_interval_remaining_percent": 100,
  "current_weekly_remaining_percent": 100
}

Notice: counts are 0/0, both statuses are 3 (different from general, which is 1), yet *_remaining_percent is 100.

mmx quota show (text mode, region = cn)

| video           100% 剩余  [................]   0%                  |
|   └ 每周 100% 剩余                                   重置于 6h 39m  |

(The general row, in the same response, correctly shows 63% / 96% remaining with non-zero counts.)

mmx video generate response

{
  "task_id": "",
  "base_resp": {
    "status_code": 2056,
    "status_msg": "usage limit exceeded, weekly usage limit reached for Token Plan Plus (0/0 used), resets at 2026-06-15T00:00:00+08:00"
  }
}

status_code: 2056, message explicitly says (0/0 used) for the same plan + same model + same week that quota show reported as 100% remaining.

Expected output

The quota endpoint should agree with the generation endpoint. Concretely, one of:

  • Server-side fix (preferred) — when the model is not part of the user's plan (e.g. current_interval_total_count === 0 AND current_weekly_total_count === 0 AND *_status === 3), the /v1/token_plan/remains response should return something the CLI can show truthfully:
    • current_interval_remaining_percent: 0 and current_weekly_remaining_percent: 0 (consistent with (0/0 used)), or
    • a new field like model_name: "video", available_in_plan: false (or an explicit status: "not_in_plan") so the CLI can render "video — not in your Token Plan Plus" instead of a misleading "100% remaining".
  • CLI-side fallback — if the server is hard to change, the CLI could detect current_interval_total_count === 0 && current_weekly_total_count === 0 && current_interval_status === 3 and render the row as 0% 剩余 — not in your current plan (or similar) so the user is not sent straight into mmx video generate only to be turned away with 2056.

Either way, the user-facing experience should not say "100% remaining" and then "0/0 used" within the same minute for the same plan.

Root cause (hypothesis)

The /v1/token_plan/remains response is being computed in a way that conflates "no usage so far" with "no allowance at all". For plans where a model is not bundled (Token Plan Plus does not include video), the server returns:

  • count fields = 0 (correct: there is no quota bucket)
  • percent fields = 100 (wrong: this is computed as 100% of 0, not as a real remaining-quota signal)
  • status = 3 (a status code whose meaning is undocumented in the public API; "not in plan" is the only interpretation consistent with the generation endpoint's (0/0 used))

Meanwhile /v1/video_generation enforces the real plan: (0/0 used) because the model is not in the plan at all. The two endpoints are not derived from the same source of truth.

The fix in #165 made the panel render the percent fields, which now carries this inconsistency straight to the user.

Suggested fix

Option A — server-side (preferred)

Make /v1/token_plan/remains and /v1/video_generation agree. Concretely, when a model is not bundled in the user's plan:

{
  "model_name": "video",
  "current_interval_total_count": 0,
  "current_interval_usage_count": 0,
  "current_weekly_total_count": 0,
  "current_weekly_usage_count": 0,
  "current_interval_remaining_percent": 0,
  "current_weekly_remaining_percent": 0,
  "current_interval_status": 4,            // new: "not_in_plan"
  "current_weekly_status": 4,
  "not_in_plan": true
}

…so the CLI can render video — 不在当前套餐中 / not in your plan, and the user can decide whether to upgrade before re-running the generation call.

Option B — CLI-side guardrail (defense in depth, can ship immediately)

In mmx quota show, when current_interval_total_count === 0 && current_weekly_total_count === 0 && current_interval_status !== 1 (the "no bucket" case), render the row as:

| video          不在当前套餐中  [................]   0%           |
|   └ 每周 不在当前套餐中                              —            |

…regardless of what the *_remaining_percent fields say. This way the user is never told "100% remaining" for a model they cannot use.

Bonus: a preflight check in mmx video generate — if the quota endpoint reports this "no bucket" state, fail fast with a clear error like video generation is not included in your Token Plan Plus. Upgrade your plan at <url>. instead of submitting a task and getting a 2056 back. The current 2056 message is correct, but only the user who reads the raw JSON sees it; the CLI swallows the message into a generic "Task failed" unless --verbose is on.

Related

Reproduction environment

  • macOS 15.x
  • mmx 1.0.16
  • API endpoint 1: GET https://api.minimaxi.com/v1/token_plan/remains
  • API endpoint 2: POST https://api.minimaxi.com/v1/video_generation
  • Reproduction key: Token Plan Plus, region cn, video model = MiniMax-Hailuo-2.3 (default)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions