anomalyco / anomalyco/opencode

Zen x-preview-f-free returns string "null" for nullable string tool arguments

Open
#44,262 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

The OpenCode Zen x-preview-f-free route returns the string "null" for a
tool argument declared as string | null. The same request to
nemotron-3-ultra-free returns JSON null.

Ox Alpha response:

{"nullableValue":"null"}

Nemotron response:

{"nullableValue":null}

The wrong type is present in the raw
choices[0].message.tool_calls[0].function.arguments response from Zen, before
an OpenCode client or AI SDK parses it.

I also tested strict: true, anyOf, oneOf, reversed union order, and
OpenAPI-style nullable: true. Ox Alpha returned the string "null" in every
case. It returned JSON null for a null-only schema and for unions of null with
integer, boolean, number, object, or array. The failure appears specific to
nullable strings on this route.

This breaks any tool that uses null as the no-value form for a string field,
including paths and object IDs.

Plugins

None. The reproduction calls the public Zen endpoint directly.

OpenCode version

The client integration uses OpenCode 1.18.16. The minimal reproduction below
does not use the client.

Steps to reproduce

Run this keyless request:

curl -sS https://opencode.ai/zen/v1/chat/completions \
  -H 'Authorization: Bearer public' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "model": "x-preview-f-free",
    "messages": [{
      "role": "user",
      "content": "Call probe_tool exactly once. nullableValue is JSON null. Preserve JSON types."
    }],
    "tools": [{
      "type": "function",
      "function": {
        "name": "probe_tool",
        "description": "Schema compatibility probe",
        "parameters": {
          "type": "object",
          "properties": {
            "nullableValue": {
              "type": ["string", "null"]
            }
          },
          "required": ["nullableValue"],
          "additionalProperties": false
        }
      }
    }],
    "tool_choice": {
      "type": "function",
      "function": {"name": "probe_tool"}
    },
    "stream": false
  }' | jq -r '.choices[0].message.tool_calls[0].function.arguments'

Observed:

{"nullableValue":"null"}

Change only model to nemotron-3-ultra-free. The result is:

{"nullableValue":null}

A client compatibility lowering works on Ox Alpha: advertise the field as an
optional string and decode omission back to null. In two no-value probes, Ox
Alpha returned {}. When given a string, it returned
{"nullableValue":"abc123"}.

Screenshot and/or share link

None.

Operating System

macOS

Terminal

zsh

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the keyless curl reproduction against the OpenCode Zen chat completions endpoint and compare x-preview-f-free with nemotron-3-ultra-free. Inspect the raw tool-call arguments before client parsing, including the nullable string schema cases described. Done means determining the route-level cause and returning JSON null rather than the string "null".

Written by the indexing model from the issue text.

Assessment

Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.