Skip to content

uploads create sends JSON to a multipart/form-data endpoint — the command can never succeed #70

Description

@barberscott

Summary

omni uploads create can never succeed. The command is generated for a multipart/form-data endpoint and its --schema output shows a file parameter, but the CLI sends the request body as JSON — so the server rejects every invocation.

The OpenAPI spec is correct here — the endpoint declares content: multipart/form-data with file: {type: string, format: binary}, which is the standard OpenAPI 3 encoding for a file part. The CLI reads the body schema but discards the media type it is declared under, so this is a CLI-side consumption bug rather than a spec problem.

POST /api/v1/uploads is currently the only multipart/form-data endpoint in the spec, which is likely why this path was never exercised.

Reproduction

omni uploads create --body '{"file":"/path/to/data.csv","modelId":"<model-uuid>","viewName":"my_view"}'

Observed

{"detail":"Invalid request. Expected multipart/form-data.","status":400}
Error: API returned HTTP 400

There is no --file flag, and no value of file in the JSON body can work — the transport itself is wrong, not the payload.

Expected

The CSV is uploaded and the command returns the created upload (id, viewName, rowCount, viewCreated).

Why it happens

Three things combine:

  1. internal/openapi/generate.gorequestBodySchema() prefers application/json and otherwise falls back to the first declared media type. For this endpoint that's the multipart schema, so the command is generated and --schema renders the file field (type: string, format: binary) as though it were sendable.
  2. internal/auth/auth.go — every request hardcodes Content-Type: application/json.
  3. There is no multipart machinery anywhere in the CLI (no mime/multipart use, no file reading for request bodies).

Net effect: the generator emits a command whose declared interface can't be honored by the transport.

Workaround

Call the endpoint directly:

curl -X POST "$OMNI_BASE_URL/api/v1/uploads" \
  -H "Authorization: Bearer $OMNI_TOKEN" \
  -F "modelId=<model-uuid>" \
  -F "viewName=my_view" \
  -F "file=@/path/to/data.csv"

Every other step in an upload-backed workflow (creating the draft, patching the tab, publishing) works through the CLI — only this one call has to bypass it.

Environment

  • CLI built from main with a current spec sync
  • Reproduced against a current API deployment

Filed by Claude on behalf of @barberscott.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions