Skip to content

ai to-markdown never sends a files file part, so every conversion fails with 6006 #463

Closed

Description

@hajikelu

Summary of the issue

cf ai to-markdown fails with [6006] Error converting to markdown. I hit it with an HTML file, but the cause applies to any file. The endpoint takes the files in a multipart field named files, and the generated command never sends a file part with that name:

  • --file <path> sends a file part named file. The API has no file field.
  • --files <value>, including --files @<path>, sends files as a text part.

The OpenAPI definition the commands are generated from (Forge release openapi@e2d50301) declares the field as a required array of binary strings:

"files": {
  "description": "Files to convert, supplied as multipart file uploads.",
  "type": "array",
  "items": { "format": "binary", "type": "string" }
}

The generator at 350c808 doesn't treat an array of binary strings as a file field:

  • isBinary is true only for a single format: binary value, so files isn't binary and the generator picks no payloadField:
    const isBinary = isScalar(resolved, "binary");
  • With no payloadField, --file falls back to the name file:
    const payload = info.payloadField ?? "file";
  • files goes through the branch for ordinary array fields, which appends it as a string:
    case "object":
    case "array":
    lines.push(` if (${read} !== undefined) {`);
    lines.push(
    ` const v = typeof ${read} === 'string' ? resolveFileToken(${read}, '${flag}', 'text') : ${read};`
    );
    lines.push(
    ` formData.append('${f.name}', typeof v === 'string' ? v : JSON.stringify(v));`
    );
    lines.push(" }");

#272 (the fix for #177) only added file flags for fields where isBinary is true, so this command didn't change, and 1.0.0-beta.26 fails the same way 1.0.0-beta.21 did.

A fix could treat an array whose items are format: binary as a file field and send each path as its own files part. The regression snapshot ai/to-markdown.snap in #290 records the current --file request (a part named file with application/octet-stream), so if #290 lands first, the fix will need to update that snapshot.

Expected behaviour

cf ai to-markdown uploads each file as a file part named files, with its filename, and prints the conversion result for each file. The request matches the one in the REST API docs:

curl https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/tomarkdown \
  -X POST \
  -H 'Authorization: Bearer {API_TOKEN}' \
  -F "files=@cat.jpeg" \
  -F "files=@somatosensory.pdf"

Because files is an array, the flag should accept more than one file.

Version of cf used

1.0.0-beta.26

System information and package versions

System:
  OS: Linux 7.2 Ubuntu 26.04.1 LTS 26.04.1 LTS (Resolute Raccoon)
  CPU: (8) x64 Intel(R) Core(TM) i5-10310U CPU @ 1.70GHz
  Memory: 12.06 GB / 15.25 GB
  Container: Yes
  Shell: 5.3.9 - /bin/bash
Binaries:
  Node: 26.13.0 - /home/hjkl/.local/share/mise/installs/node/26.13.0/bin/node
  Yarn: 4.18.1 - /home/hjkl/.local/share/vite-plus/fallback-bin/yarn
  npm: 11.20.0 - /home/hjkl/.local/share/mise/installs/node/26.13.0/bin/npm
  pnpm: 12.16.1 - /home/hjkl/.local/share/mise/installs/pnpm/12.16.1/pnpm
  bun: 1.4.4 - /home/hjkl/.local/share/vite-plus/fallback-bin/bun
  Deno: 2.9.8 - /home/hjkl/.local/share/mise/installs/deno/2.9.8/bin/deno
npmPackages:
  @cloudflare/vite-plugin: 2.0.0-beta.v.8 => 2.0.0-beta.v.8
  cf: 1.0.0-beta.26 => 1.0.0-beta.26

Reproduction (optional)

printf '<h1>Hello</h1>\n' > sample.html
cf ai to-markdown --file sample.html
cf ai to-markdown --files @sample.html

Both commands fail with 6006. cf ai list-markdown-supported-formats lists .html with text/html, and HTML conversion through the Workers AI binding (env.AI.toMarkdown()) works in my Worker.

To see what cf sends, I pointed CLOUDFLARE_API_BASE_URL at a local server that parses the multipart body and prints each part. The first line below comes from --file, the second from --files @sample.html:

part "file": file name="sample.html" type="application/octet-stream" content="<h1>Hello</h1>\n"
part "files": text "<h1>Hello</h1>\r\n"

Relevant error logs (optional)

┌ APIError
│ [6006] Error converting to markdown
│ 400 Bad Request · HTTP /accounts/<account-id>/ai/tomarkdown
└
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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