Skip to content

STO-67: fast-fail Model Repo storage quota check - #338

Open
jebenexer wants to merge 1 commit into
mainfrom
benjaminbrannaka/sto-67-model-repo-storage-limit
Open

STO-67: fast-fail Model Repo storage quota check#338
jebenexer wants to merge 1 commit into
mainfrom
benjaminbrannaka/sto-67-model-repo-storage-limit

Conversation

@jebenexer

@jebenexer jebenexer commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Resolves STO-67.
Server-side counterpart: runpod/RunPod#5929.

#339 (STO-366, pre-signed URL batching) is independent — this check runs before
session creation either way.

Problem

runpodctl already knows the total model size before uploading, but goes
straight into session creation with no check against the account's storage
quota. An over-quota upload should fail immediately with a useful message,
not after creating a model and partial upload sessions server-side.

Changes

  • api.GetModelRepoStorageUsage wraps the new modelRepoStorageUsage query.
  • checkModelRepoStorageQuota compares the total upload size against
    availableBytes and returns an actionable error when it would be exceeded.
    It fails open: a query error or unparseable response warns and proceeds,
    since a client-side pre-check must never itself break a valid upload. Skipped
    when enforcement is off (Enforced: false) or no quota is set
    (AvailableBytes: nil). createModelRepoUpload's server-side gate is still
    the real limit.
  • Wired into runAddModel after file-name/file-size validation and before
    addModelToRepo, covering both --model-path and single-file flows.

Testing

  • go vet ./..., go build ./..., go test ./..., govulncheck ./...
  • checkModelRepoStorageQuota allow/deny/boundary/fail-open, and
    modelUploadRequestedBytes' directory-vs-flag size resolution.
  • API-level tests for GetModelRepoStorageUsage, including its entry in the
    STO-357 typed-error table.
  • End-to-end test confirming addModelToRepo and createModelRepoUpload are
    never reached when the check rejects the upload.

Note

Low Risk
Adds an optional pre-upload check that fails open on API errors; no change to server enforcement or non-upload flows (e.g. Hugging Face mirror).

Overview
Adds a client-side Model Repo storage quota pre-check so runpodctl model add can reject over-quota uploads before addModelToRepo or upload sessions are created.

The API layer gains ModelRepoStorageUsage and GetModelRepoStorageUsage, calling the modelRepoStorageUsage GraphQL query (optional owner, byte fields as strings). In model add, checkModelRepoStorageQuota compares the planned upload size—from --model-path totals or --file-size—against availableBytes when enforced is true, returning a clear error if the upload would exceed quota. The check fails open on query/parse errors (stderr warning only) so the CLI never blocks uploads when usage cannot be read; server-side enforcement on createModelRepoUpload remains authoritative. Quota validation runs after upload flag validation and before any model creation.

Tests cover API parsing/GraphQL errors, quota allow/deny/boundary/fail-open behavior, byte-size resolution, and an integration case that addModelToRepo / createModelRepoUpload are not invoked when over quota.

Reviewed by Cursor Bugbot for commit 36a185e. Configure here.

Adds a client-side check that fails fast, before creating the model or
a single upload session, when a local upload would exceed the account's
Model Repo storage quota.

- api.GetModelRepoStorageUsage: wraps the server's modelRepoStorageUsage
  query (runpod/RunPod#5929).
- checkModelRepoStorageQuota: compares the total local upload size
  against availableBytes and returns a clear, actionable error when it
  would be exceeded. Fails OPEN on any query error or unparseable
  response (older server, transient network issue) -- a client-side
  pre-check must never itself become the reason an otherwise-valid
  upload fails. Skipped entirely when enforcement is disabled
  server-side.
- Wired into runAddModel right after the existing file-name/file-size
  validation, before addModelToRepo is called for either the
  --model-path (directory) or single-file (--file-name/--file-size)
  upload flows.
- Storage-usage query failures go through modelRepoHTTPError/
  modelRepoGraphQLError like the rest of the model-repo API surface, so
  access-denied and other server errors carry a stable error code (the
  STO-357 contract) rather than a bare string.

Testing: go build/vet/test clean across the whole module.
- cmd/model/modelRepoQuota_test.go covers the quota check's
  allow/deny/boundary/fail-open behavior and modelUploadRequestedBytes'
  directory-vs-flag size resolution.
- api/model_test.go covers GetModelRepoStorageUsage response parsing,
  owner-variable omission, and graphql error surfacing, and the
  model-repo access-denied table test gains an entry for it.
- One end-to-end test confirms addModelToRepo/createModelRepoUpload are
  never called when the fast-fail check rejects the upload.
@jebenexer
jebenexer force-pushed the benjaminbrannaka/sto-67-model-repo-storage-limit branch from 45f8fcf to 36a185e Compare September 10, 2026 03:06
@jebenexer

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 36a185e. Configure here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant