Repository navigation
JavaScript heap out of memory when compiling typesafe-joi on v3.4.x #30794
Description
Activity
I am debugging TypeScript using the tag v3.4.1. I pause the execution of tsc randomly in vscode and analyze the call stack. Here are what I know about what TypeScript is doing:
- Look into the file src/schema/object.ts
- Check the heritage element
ObjectSchemaType<ObjectSchema, Value>ofObjectSchema - Check
ObjectSchemaType.allowagainstAbstractSchema.allow allowis using the typeObjectSchema- Back to 2 with somewhere in the type parameters substituted with
? - After several rounds, TypeScript finally completes checking
allow - Start checking
ObjectSchemaType.keys - and so on...
Seems that ts is doing type check very slowly so every time I pause the stack tells me the same thing.
Increasing heap memory limit does not help. tsc will eat up all memory. There seems a infinity loop consuming lots of memory.
node --max-old-space-size=8192 node_modules/typescript/bin/tsc -p typesafe-joi-issue
Reacted by Steve Dimock, Erick Benites Cuenca and Sam ThomsonThe same issue with me, the new version of
tschas ruined (overly limited) my complex type hierarchy so that the compiler crashes when tries to process it.Also experiencing this issue -
v3.3.3works as expected.Same here when compiling application with large type hierarchies.
Previous versions (3.3) of tsc work fine.After upgrading to TS 3.4.3 we started to have out of memory issues with karma 3.0.0, karma-webpack 3.0.5 and awesome-typescript-loader 5.2.1
Downgrading to TS 3.3.3 solved the issue for us
Here is the issue we had:
06:24:09 10 04 2019 10:24:10.023:DEBUG [preprocessor.sourcemap]: base64-encoded source map for /usr/src/app/test/unit/index.ts 06:24:14 06:24:14 <--- Last few GCs ---> 06:24:14 06:24:14 [22:0x41366c0] 93441 ms: Mark-sweep 1136.6 (1442.4) -> 1136.2 (1432.9) MB, 1065.9 / 0.1 ms allocation failure GC in old space requested 06:24:14 [22:0x41366c0] 94547 ms: Mark-sweep 1136.2 (1432.9) -> 1136.2 (1363.9) MB, 1105.6 / 0.0 ms last resort GC in old space requested 06:24:14 [22:0x41366c0] 95623 ms: Mark-sweep 1136.2 (1363.9) -> 1136.2 (1334.4) MB, 1076.1 / 0.2 ms last resort GC in old space requested 06:24:14 06:24:14 06:24:14 <--- JS stacktrace ---> 06:24:14 06:24:14 ==== JS stack trace ========================================= 06:24:14 06:24:14 Security context: 0xfecfb0a57c1 <JSObject> 06:24:14 1: toString [buffer.js:611] [bytecode=0x198b036e3f71 offset=31](this=0x28d61df02251 <Uint8Array map = 0x89f7ce11f59>,encoding=0x2bf242822d1 <undefined>,start=0x2bf242822d1 <undefined>,end=0x2bf242822d1 <undefined>) 06:24:14 2: arguments adaptor frame: 0->3 06:24:14 3: /* anonymous */(aka /* anonymous */) [/usr/src/app/node_modules/karma-webpack/lib/karma-webpack.js:324] [bytecode=0x1a6fc83e59b9 offset=... 06:24:14 06:24:14 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 06:24:14 1: node::Abort() [gulp] 06:24:14 2: 0x11e7fec [gulp] 06:24:14 3: v8::Utils::ReportOOMFailure(char const*, bool) [gulp] 06:24:14 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [gulp] 06:24:14 5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [gulp] 06:24:14 6: v8::internal::Factory::NewStringFromUtf8(v8::internal::Vector<char const>, v8::internal::PretenureFlag) [gulp] 06:24:14 7: v8::String::NewFromUtf8(v8::Isolate*, char const*, v8::NewStringType, int) [gulp] 06:24:14 8: node::StringBytes::Encode(v8::Isolate*, char const*, unsigned long, node::encoding, v8::Local<v8::Value>*) [gulp] 06:24:14 9: 0x1207c96 [gulp] 06:24:14 10: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [gulp] 06:24:14 11: 0xb7a9ac [gulp] 06:24:14 12: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [gulp] 06:24:14 13: 0xc10cfc842fdReacted by Ivan VoznyakovskyRyanCavanaugh commented
on Apr 10, 2019 MemberMore actionsGetting a minimal repro
Ryan Cavanaugh (@RyanCavanaugh) it seems this oneliner does it: #30831
RyanCavanaugh commented
on Apr 10, 2019 MemberMore actionsHere's the smallest (!) repro I have
interface AbstractSchema<S, V> { m1<T> (v: T): SchemaType<S, Exclude<V, T>>; m2<T> (v: T): SchemaType<S, T>; } type SchemaType<S, V> = S extends object ? AnySchema<V> : never; interface AnySchema<V> extends AnySchemaType<AnySchema<undefined>, V> { } interface AnySchemaType<S extends AbstractSchema<any, any>, V> extends AbstractSchema<S, V> { }
Reacted by Jingkun HuaRyanCavanaugh commented
on Apr 10, 2019 MemberMore actions- addedBugA bug in TypeScriptA bug in TypeScriptCrashFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad outputFor flagging bugs which are compiler or service crashes or unclean exits, rather than bad output
on Apr 10, 2019 The issue is runaway recursion in
isTypeIdenticalTowhich is set off by code that attempts to simplify conditional types. I just put up a PR that switches the check to just use object identity.- addedFixedA PR has been merged for this issueA PR has been merged for this issue
on Apr 12, 2019 - locked as resolved and limited conversation to collaborators
on Oct 21, 2025
TypeScript Version:
3.4.1, 3.4.2, 3.5.0-dev.20190406
Reproduction:
https://github.com/hjkcai/typesafe-joi/tree/feature/split-files
git clone https://github.com/hjkcai/typesafe-joi.git -b feature/split-files --depth=1 yarn yarn testUpdate: the published version also has this problem. Reproduce using the published version:
Expected behavior:
tsc should work. It works in ts 3.3.
Actual behavior:
tsc -p .TypeScript Server: canceled request with sequence number xxx)Related Issues:
I saw lots of regression issues about recursion and type inference. typesafe-joi uses lots of recursions. Maybe they are somehow related?
typesafe-joi was crashed once (#28873). Jordi Oliveras Rovira (@j-oliveras) Anders Hejlsberg (@ahejlsberg) Please help!