orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
3.11k stars 335 forks source link

Out of memory error using zod client #1642

Open patrickhuijten opened 1 month ago

patrickhuijten commented 1 month ago

What are the steps to reproduce this issue?

  1. Add client: "zod" to the orval config file
  2. Run orval

I tested this both on my mac locally and inside a docker build container.

What happens?

When adding zod as a client, the node process runs out of memory due to what looks like a memory leak.

What were you expecting to happen?

For the process to terminate successfully.

Any logs, error output, etc?

// orval.config.ts
import { defineConfig } from "orval";

const input = {
  target: "", // redacted
  validation: false,
};

const output = {
  mode: "tags",
  target: "./src/generated/api",
  schemas: "./src/generated/model",
  mock: true,
  prettier: true,
} as const;

export default defineConfig({
  client: {
    output,
    input,
  },
  zod: {
    output: {
      ...output,
      target: "./src/generated/zod",
      client: "zod",
      fileExtension: ".zod.ts",
    },
    input,
  },
});
$ orval --config ./orval.config.ts
🍻 Start orval v7.1.1 - A swagger client generator for typescript
🎉 client - Your OpenAPI spec has been converted into ready to use orval!

<--- Last few GCs --->

[90599:0x128008000]    28075 ms: Mark-Compact 4049.9 (4137.2) -> 4035.7 (4139.0) MB, 958.38 / 0.00 ms  (average mu = 0.120, current mu = 0.013) allocation failure; scavenge might not succeed
[90599:0x128008000]    29185 ms: Mark-Compact 4051.6 (4139.0) -> 4037.8 (4141.0) MB, 1098.46 / 0.00 ms  (average mu = 0.063, current mu = 0.010) allocation failure; scavenge might not succeed

<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

 1: 0x1000e35a4 node::OOMErrorHandler(char const*, v8::OOMDetails const&) [/usr/local/bin/node]
 2: 0x10026c04c v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [/usr/local/bin/node]
 3: 0x100440720 v8::internal::Heap::GarbageCollectionReasonToString(v8::internal::GarbageCollectionReason) [/usr/local/bin/node]
 4: 0x1004445d4 v8::internal::Heap::CollectGarbageShared(v8::internal::LocalHeap*, v8::internal::GarbageCollectionReason) [/usr/local/bin/node]
 5: 0x100441038 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::internal::GarbageCollectionReason, char const*) [/usr/local/bin/node]
 6: 0x10043edc0 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
 7: 0x100435a14 v8::internal::HeapAllocator::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
 8: 0x100436274 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
 9: 0x10041b2e4 v8::internal::Factory::NewFillerObject(int, v8::internal::AllocationAlignment, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/usr/local/bin/node]
10: 0x100802ff4 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
11: 0x100b60c44 Builtins_CEntry_Return1_ArgvOnStack_NoBuiltinExit [/usr/local/bin/node]
12: 0x100b2b354 Builtins_CloneObjectIC_Slow [/usr/local/bin/node]
13: 0x1063cd41c
14: 0x1063d3090
15: 0x1063ce4e8
16: 0x1063d3090
17: 0x1063ce4e8
18: 0x1063d3090
19: 0x1063ce4e8
20: 0x1063d3090
21: 0x1063ce4e8
22: 0x1063d3090
23: 0x1063ce4e8
24: 0x1063d3090
25: 0x1063fac24
26: 0x100b83ee4 Builtins_ArrayMap [/usr/local/bin/node]
27: 0x1063d3054
28: 0x1063ce4e8
29: 0x1063d3090
30: 0x1063ce4e8
31: 0x1063d3090
32: 0x1063ce4e8
33: 0x1063d3090
34: 0x1063ce4e8
35: 0x1063d3090
36: 0x1063ce4e8
37: 0x1063d3090
38: 0x1063ce4e8
39: 0x1063d3090
40: 0x1063ce4e8
41: 0x1063d3090
42: 0x1063ce4e8
43: 0x1063d3090
44: 0x1063ce4e8
45: 0x1063d3090
46: 0x1063ce4e8
47: 0x1063d3090
48: 0x1063ce4e8
49: 0x1063d3090
50: 0x1063ce4e8
51: 0x1063d3090
52: 0x1063ce4e8
53: 0x1063d3090
54: 0x1063ce4e8
55: 0x1063d3090
56: 0x1063ce4e8
57: 0x1063d3090
58: 0x1063ce4e8
59: 0x1063d3090
60: 0x1063ce4e8
61: 0x1063d3090
62: 0x1063ce4e8
63: 0x1063d3090
64: 0x1063ce4e8
65: 0x1063d3090
66: 0x1063ce4e8
67: 0x1063d3090
68: 0x1063ce4e8
69: 0x1063d3090
70: 0x1063ce4e8
71: 0x1063d3090
72: 0x1063ce4e8
73: 0x1063d3090
74: 0x1063ce4e8
75: 0x1063d3090
76: 0x1063ce4e8
77: 0x1063d3090
78: 0x1063ce4e8
79: 0x1063d3090
80: 0x1063ce4e8
81: 0x1063d3090
82: 0x1063ce4e8
83: 0x1063d3090
84: 0x1063ce4e8
85: 0x1063d3090
86: 0x1063ce4e8
87: 0x1063d3090
88: 0x1063dadc4
89: 0x100b87fb4 Builtins_ArrayReduce [/usr/local/bin/node]
90: 0x1063df54c
91: 0x1063da720
92: 0x1063dadc4
93: 0x100b87fb4 Builtins_ArrayReduce [/usr/local/bin/node]
94: 0x1063df54c
95: 0x1063da720
96: 0x1063dadc4
97: 0x100b87fb4 Builtins_ArrayReduce [/usr/local/bin/node]
98: 0x1063df54c
99: 0x1063da720
100: 0x1063dadc4
101: 0x100b87fb4 Builtins_ArrayReduce [/usr/local/bin/node]
102: 0x1063df54c
103: 0x1063da720
104: 0x1063dadc4
105: 0x100b87fb4 Builtins_ArrayReduce [/usr/local/bin/node]
106: 0x1063df54c
107: 0x100ad83e4 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
108: 0x100ad83e4 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
109: 0x100b83ee4 Builtins_ArrayMap [/usr/local/bin/node]
110: 0x100ad83e4 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
111: 0x100ad83e4 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
112: 0x106330660
113: 0x1063117f8
114: 0x10633759c
115: 0x10634f7b4
116: 0x100b0f210 Builtins_AsyncFunctionAwaitResolveClosure [/usr/local/bin/node]
117: 0x100bbcfb8 Builtins_PromiseFulfillReactionJob [/usr/local/bin/node]
118: 0x100afeb94 Builtins_RunMicrotasks [/usr/local/bin/node]
119: 0x100ad63f4 Builtins_JSRunMicrotasksEntry [/usr/local/bin/node]
120: 0x1003adba0 v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [/usr/local/bin/node]
121: 0x1003ae08c v8::internal::(anonymous namespace)::InvokeWithTryCatch(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [/usr/local/bin/node]
122: 0x1003ae268 v8::internal::Execution::TryRunMicrotasks(v8::internal::Isolate*, v8::internal::MicrotaskQueue*) [/usr/local/bin/node]
123: 0x1003d5434 v8::internal::MicrotaskQueue::RunMicrotasks(v8::internal::Isolate*) [/usr/local/bin/node]
124: 0x1003d5bd0 v8::internal::MicrotaskQueue::PerformCheckpoint(v8::Isolate*) [/usr/local/bin/node]
125: 0x1002d9bc8 v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, unsigned long*, int) [/usr/local/bin/node]
126: 0x1002d92c0 v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
127: 0x100b60b24 Builtins_CEntry_Return1_ArgvOnStack_BuiltinExit [/usr/local/bin/node]
128: 0x106156c48
129: 0x100ad650c Builtins_JSEntryTrampoline [/usr/local/bin/node]
130: 0x100ad61f4 Builtins_JSEntry [/usr/local/bin/node]
131: 0x1003adbc8 v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [/usr/local/bin/node]
132: 0x1003ad014 v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) [/usr/local/bin/node]
133: 0x100287904 v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) [/usr/local/bin/node]
134: 0x10000cd24 node::InternalCallbackScope::Close() [/usr/local/bin/node]
135: 0x10000cfe4 node::InternalMakeCallback(node::Environment*, v8::Local<v8::Object>, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*, node::async_context) [/usr/local/bin/node]
136: 0x100023068 node::AsyncWrap::MakeCallback(v8::Local<v8::Function>, int, v8::Local<v8::Value>*) [/usr/local/bin/node]
137: 0x1001b0ca8 node::StreamBase::CallJSOnreadMethod(long, v8::Local<v8::ArrayBuffer>, unsigned long, node::StreamBase::StreamBaseJSChecks) [/usr/local/bin/node]
138: 0x1001b2334 node::EmitToJSStreamListener::OnStreamRead(long, uv_buf_t const&) [/usr/local/bin/node]
139: 0x100224d28 node::crypto::TLSWrap::ClearOut() [/usr/local/bin/node]
140: 0x100226adc node::crypto::TLSWrap::OnStreamRead(long, uv_buf_t const&) [/usr/local/bin/node]
141: 0x1001b6620 node::LibuvStreamWrap::OnUvRead(long, uv_buf_t const*) [/usr/local/bin/node]
142: 0x1001b6d54 node::LibuvStreamWrap::ReadStart()::$_1::__invoke(uv_stream_s*, long, uv_buf_t const*) [/usr/local/bin/node]
143: 0x100ac1d24 uv__stream_io [/usr/local/bin/node]
144: 0x100ac9628 uv__io_poll [/usr/local/bin/node]
145: 0x100ab7b14 uv_run [/usr/local/bin/node]
146: 0x10000d6f0 node::SpinEventLoopInternal(node::Environment*) [/usr/local/bin/node]
147: 0x1001233f0 node::NodeMainInstance::Run(node::ExitCode*, node::Environment*) [/usr/local/bin/node]
148: 0x100123104 node::NodeMainInstance::Run() [/usr/local/bin/node]
149: 0x1000aafa0 node::Start(int, char**) [/usr/local/bin/node]
150: 0x18750d0e0 start [/usr/lib/dyld]
error Command failed with signal "SIGABRT".

What versions are you using?

  Programs:
   node: v20.17.0

  System:
    OS: macOS 14.3
    CPU: (11) arm64 Apple M3 Pro
    Memory: 1.41 GB / 18.00 GB
    Shell: 5.9 - /bin/zsh

  npmPackages:
    orval: 7.1.1 => 7.1.1 
melloware commented 1 month ago

I think your issue is similar to this one: https://github.com/orval-labs/orval/issues/967

Is your OpenAPI spec large or complex by any chance?

patrickhuijten commented 3 weeks ago

Hi @melloware, I don't think it's particularly large (~64kb). I'm not sure what would count towards complexity but it has a few instances of allOf but really nothing out of the ordinary. I think our spec is not private: https://api.edge.promaton.com/docs/public/openapi.json

melloware commented 3 weeks ago

yeah i suspect something is getting into an infinite loop?