# JSON3 stack overflow with generics

**URL:** <https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648>\
**Category:** General Usage\
**Created:** [September 22, 2022, 2:11pm UTC](https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648 "2022-09-22T14:11:23Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lklein](https://avatars.discourse-cdn.com/v4/letter/l/839c29/32.png) [@lklein](https://discourse.julialang.org/u/lklein)\
**Post date:** [September 22, 2022, 2:11pm UTC](https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648/1 "2022-09-22T14:11:23Z")

</div>

When running the following code, I get a StackOverflow error.  
I do not understand why that error happens. It seems to have something to do with the compilers reasoning about generics.  
Any input on why that error happens and what it means would be greatly appreciated.

```julia
using JSON3
using StructTypes

struct A{T}
    name::String
end

struct B{T}
    default::Ref{Union{T,Nothing}}
end

StructTypes.StructType(::Type{A{T}}) where T = StructTypes.Struct()

StructTypes.StructType(::Type{B{T}}) where T = StructTypes.Struct()

function f(settings::Vector{A})
    for setting_template in settings
        g(setting_template)
    end
end

function g(setting_template::A{T}) where T
    json_string = ""
    JSON3.read(json_string, B{T})
end

a1 = A{Int}("a")
a2 = A{Bool}("b")

f([a1,a2])

```

When executing this code I get the following output:  
(after that an error is thrown because we try to JSON3.read an empty string, please disregard)

> Internal error: encountered unexpected error in runtime:  
> StackOverflowError()  
> subtype\_ccheck at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:546  
> var\_lt at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:618  
> subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1231  
> var\_lt at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:612  
> subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1231  
> exists\_subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1395 [inlined]  
> forall\_exists\_subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1423  
> subtype\_ccheck at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:555  
> var\_lt at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:618  
> subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1231  
> var\_lt at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:612  
> subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1231  
> exists\_subtype at /cygdrive/c/buildbot/worker/package\_win64/build/src\subtype.c:1395 [inlined]  
> …  
> unknown function (ip: 000000005f039e23)  
> with\_logstate at .\logging.jl:511  
> with\_logger at .\logging.jl:623 [inlined]  
> #63 at c:\Users\lklein.vscode\extensions\julialang.language-julia-1.7.12\scripts\packages\VSCodeServer\src\eval.jl:225  
> unknown function (ip: 000000005f0381e3)  
> jl\_apply at /cygdrive/c/buildbot/worker/package\_win64/build/src\julia.h:1788 [inlined]  
> jl\_f\_\_call\_latest at /cygdrive/c/buildbot/worker/package\_win64/build/src\builtins.c:757  
> #invokelatest#2 at .\essentials.jl:716 [inlined]  
> invokelatest at .\essentials.jl:714  
> jl\_apply at /cygdrive/c/buildbot/worker/package\_win64/build/src\julia.h:1788 [inlined]  
> do\_apply at /cygdrive/c/buildbot/worker/package\_win64/build/src\builtins.c:713  
> macro expansion at c:\Users\lklein.vscode\extensions\julialang.language-julia-1.7.12\scripts\packages\VSCodeServer\src\eval.jl:34 [inlined]  
> #61 at .\task.jl:429  
> unknown function (ip: 000000005f015ec3)  
> jl\_apply at /cygdrive/c/buildbot/worker/package\_win64/build/src\julia.h:1788 [inlined]  
> start\_task at /cygdrive/c/buildbot/worker/package\_win64/build/src\task.c:877

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [September 23, 2022, 8:03am UTC](https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648/2 "2022-09-23T08:03:15Z")

</div>

> [@lklein](#):
>
> ```julia
> struct B{T}
> default::Ref{Union{T,Nothing}}
> end
> 
> ```

Can you try this instead:

```julia
struct B{T}
    default::Union{T,Nothing}
end

```

---

<div class="post-metadata">

**Author:** ![lklein](https://avatars.discourse-cdn.com/v4/letter/l/839c29/32.png) [@lklein](https://discourse.julialang.org/u/lklein)\
**Post date:** [September 23, 2022, 2:07pm UTC](https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648/3 "2022-09-23T14:07:34Z")

</div>

Thanks for your reply!  
When running with your suggested change, the error no longer happens.  
Unfortunately that does not fix my problem, as I have a lot of side constrains and just posted a MWE to reproduce the bug.  
Any idea on why exactly that change causes the bug to happen/not happen?

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [September 26, 2022, 10:52am UTC](https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648/4 "2022-09-26T10:52:57Z")

</div>

The stack overflow seems to happen during type inference itself. The code here doesn’t have anything obvious that would lead to that, so the issue must be with the `StructType` declarations.

`StructTypes.Struct` says it should be used when a type’s “fields should be used directly when serializing/deserializing”. `B`’s field is a `Ref` which I don’t think should be _directly_ serialized/deserialized. @jd-foster’s suggestion changes `B` to have a type that _can_ be directly serialized, so makes it appropriate for `StructTypes.Struct`. But if that’s infeasible due to other constraints, you may have to change its `StructType` to `Mutable` or `Custom`. Opening an [issue](https://github.com/JuliaData/StructTypes.jl/issues) and asking the StructTypes devs would probably help with deciding which course to take exactly.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 26, 2022, 11:49am UTC](https://discourse.julialang.org/t/json3-stack-overflow-with-generics/87648/5 "2022-09-26T11:49:07Z")

</div>

FTR the stack overflow doesn’t reproduce on either the latest Julia release or on nightly Julia, at least on my Linux system (system stack size setting might matter).  
This doesn’t fix the issue, though.
