Skip to content

Conversation

@PaulyBearCoding
Copy link

Fixes #1679

Problem Statement

When using zodResponseFormat with Zod schemas that contain property names with whitespace characters, the generated JSON Schema produces $ref values and definition keys containing literal spaces. This causes validation failures when submitting the schema to the OpenAI API.

Root Cause

In src/_vendor/zod-to-json-schema/parseDef.ts line 134, the extract-to-root case joins path segments with underscores but doesn't sanitize the segments themselves. Path segments like "Thing With Spaces" preserve their internal spaces in the final $ref value.

The join('_') method only adds separators between array elements - it does not modify the content within individual elements.

Solution

Map over each path segment and replace all whitespace characters with underscores before joining:

```typescript
const name = item.path
.slice(refs.basePath.length + 1)
.map((segment) => segment.replace(/\s+/g, ''))
.join('
');
```

The regex /\s+/g matches all types of whitespace: spaces, tabs, newlines, and Unicode whitespace characters.

Testing

Unit tests:

  • All 18 tests pass (16 existing + 2 new)
  • Both Zod v3 and v4 compatibility confirmed
  • New test verifies $ref values and definition keys contain no spaces

Comprehensive edge cases validated:

  • Multiple consecutive spaces
  • Tabs and newlines
  • Unicode spaces (nbsp, em space, etc.)
  • Deeply nested structures
  • Valid names with underscores/hyphens preserved
  • Emoji and CJK characters
  • Performance: 0.03ms per schema generation (1000 iterations)

No breaking changes:

  • Valid identifiers (alphanumeric, underscores, hyphens) remain unchanged
  • Only whitespace characters are affected

Changes

Modified files:

  • src/_vendor/zod-to-json-schema/parseDef.ts (4 lines)
  • tests/helpers/zod.test.ts (added comprehensive test)

Fixes openai#1679

When using zodResponseFormat with property names containing spaces,
the generated JSON Schema includes $ref values with literal spaces,
causing OpenAI API validation failures.

Root cause: In parseDef.ts line 134, the extract-to-root case joins
path segments with underscores but doesn't sanitize the segments
themselves. Path segments like "Thing With Spaces" preserve their
internal spaces in the final $ref value.

Solution: Map over each path segment and replace all whitespace
characters with underscores before joining.

Changes:
- src/_vendor/zod-to-json-schema/parseDef.ts: Added .map() to sanitize
  each segment with .replace(/\s+/g, '_')
- tests/helpers/zod.test.ts: Added test verifying $ref values and
  definition keys contain no spaces

Testing:
- All 18 unit tests pass (16 existing + 2 new)
- Tested both Zod v3 and v4 compatibility
- Comprehensive edge cases: multiple spaces, tabs, newlines, Unicode
  spaces, deeply nested structures, emoji, CJK characters
- Performance: 0.03ms per schema generation (1000 iterations)
- No breaking changes: valid identifiers (underscores, hyphens,
  alphanumeric) preserved unchanged
@PaulyBearCoding PaulyBearCoding requested a review from a team as a code owner November 15, 2025 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zodResponseFormat emits $ref values and definition keys with spaces

1 participant