Skip to content

OpenAI reasoning models fail silently: hardcoded max_tokens rejected (400), and empty RIDDLE_OPENAI_REASONING still sends reasoning_effort #7

Description

@vnnkl

Environment

  • Riddle v0.2.0 (installed via remagic / AppLoad Store, takeover mode)
  • reMarkable Paper Pro (Ferrari), OS 3.27.3.0
  • Oracle: OpenAI, configured via remagic config riddle

Summary

With an OpenAI reasoning model configured (e.g. gpt-5.5), the diary drinks the ink but never replies. Every API request fails with HTTP 400, and nothing is shown on the page — the failure is only visible in journalctl -u riddle-takeover. Two separate request-building bugs cause this:

1. max_tokens is rejected by reasoning models

The request body hardcodes max_tokens (visible in the binary's request template). OpenAI's reasoning models (gpt-5.x, o-series) reject it:

riddle: http oracle base=https://api.openai.com/v1 model=gpt-5.5 max_tokens=2000 reasoning=high
riddle: oracle failed: http 400: {
  "error": {
    "message": "Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.",
    "type": "invalid_request_error",
    "param": "max_tokens",
    "code": "unsupported_parameter"
  }
}

So the app currently cannot work with any OpenAI reasoning model — including the ones the RIDDLE_OPENAI_REASONING setting exists for. Suggested fix: send max_completion_tokens (accepted by all current OpenAI models), or retry with it on this specific 400.

2. Empty RIDDLE_OPENAI_REASONING still sends reasoning_effort

After switching to gpt-4o to avoid bug 1, requests still failed, because remagic config riddle had written RIDDLE_OPENAI_REASONING= (present but empty) and the app includes reasoning_effort whenever the variable is set — even when empty:

riddle: http oracle base=https://api.openai.com/v1 model=gpt-4o max_tokens=2000 reasoning=
riddle: oracle failed: http 400: {
  "error": {
    "message": "Unrecognized request argument supplied: reasoning_effort",
    "type": "invalid_request_error"
  }
}

Deleting the line entirely fixed it. Suggested fix: treat empty as unset. (The settings schema's select with an empty-string option makes this an easy state to end up in via the config UI.)

3. (UX) API errors are invisible on the device

In both cases the page just stays blank after the ink is drunk. Since the writer can't see logs, it would help a lot if API failures surfaced in-theme on the page — e.g. "the ink blurred" / "the diary does not answer" — or at least a marker distinguishing "thinking" from "failed".

Working configuration (for anyone else hitting this)

RIDDLE_OPENAI_BASE=https://api.openai.com/v1
RIDDLE_OPENAI_MODEL=gpt-4o
# no RIDDLE_OPENAI_REASONING line at all

With that, replies stream back in ~1.3–1.9s to first chunk. Lovely app once it talks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions