Skip to content

bug(llm): OpenAI tool definitions with empty parameters rejected in strict mode #1673

@bug-ops

Description

@bug-ops

Bug

When using OpenAI providers with strict-mode function definitions (e.g., GPT-4o, GPT-4o-mini), tools with no parameters (empty struct schemas) cause `400 Bad Request`.

Observed

```
ERROR llm_call{model=gpt-5-mini}: OpenAI API error 400 Bad Request: {
"error": {
"message": "Invalid schema for function 'list_tasks': In context=(), object schema missing properties.",
"code": "invalid_function_parameters"
}
}
```

Root Cause

`ListTasksParams {}` (empty struct) generates schema `{"type": "object", "properties": {}}` via `schemars::schema_for!()`. OpenAI strict mode requires either:

  1. `additionalProperties: false` + explicit `required: []` (OpenAI docs), or
  2. Omit `parameters` entirely for no-param tools (Gemini approach, see feat(gemini): omit empty properties object for no-parameter tools #1641)

`normalize_for_openai_strict()` introduced in PR #1670 (issue #1656) correctly normalizes response schemas in `chat_typed`, but tool definition schemas in `convert_tools_to_request()` are not normalized.

Impact

Any no-parameter tool causes `400 Bad Request` when using OpenAI providers. Affected tools at minimum: `list_tasks` (SchedulerExecutor). Likely affects all other tools with empty parameters.

Fix

Apply `normalize_for_openai_strict()` to tool parameters schema in `convert_tools_to_request()` in `crates/zeph-llm/src/openai.rs`. Special case: if schema is `{type: "object", properties: {}}`, either omit `parameters` entirely (cleaner) or add `additionalProperties: false, required: []`.

Related: #1656 (response schema fix), #1641 (Gemini empty properties). Additional affected tools: SessionListParams {} in zeph-acp/src/custom.rs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingllmzeph-llm crate (Ollama, Claude)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions