Vapor Content Decode Crash On Liunx

when I start Job

app_1      | redisHost: redis
app_1      | [ NOTICE ] Server starting on http://0.0.0.0:8080
app_1      | [ INFO ] GET /job [request-id: 56B3A977-ED85-4FB7-924C-6EFB8F40C48F]
app_1      | [ INFO ] Dispatched queue job [job_id: 8D87784C-FDED-4632-A07F-48E7E50FBCE7, job_name: MirrorJob, queue: default, request-id: 56B3A977-ED85-4FB7-924C-6EFB8F40C48F]
app_1      | [ INFO ] Dequeing job [job_id: 8D87784C-FDED-4632-A07F-48E7E50FBCE7, job_name: MirrorJob, queue: default]
app_1      | [ INFO ] 开启自动任务->> [job_id: 8D87784C-FDED-4632-A07F-48E7E50FBCE7]
app_1      | [ INFO ] 开始等待镜像完毕: Optional(1331589D-7A1C-4991-8C72-AB426F035BAC) https://gitee.com/spm_mirror/LocalizedStringKit https://github.com/microsoft/LocalizedStringKit [job_id: 8D87784C-FDED-4632-A07F-48E7E50FBCE7]
app_1      | Received signal 4. Backtrace:
app_1      | 0x564a985b1892, Backtrace.(printBacktrace in _B82A8C0ED7C904841114FDF244F9E58E)(signal: Swift.Int32) -> () at /build/.build/checkouts/swift-backtrace/Sources/Backtrace/Backtrace.swift:66
app_1      | 0x7fbca8f743bf
app_1      | 0x564a99212036
app_1      | 0x564a99212d34
app_1      | 0x564a99215e53
app_1      | 0x564a9921441d
app_1      | 0x564a9921e3dd
app_1      | 0x564a9921f106
app_1      | 0x564a98e7fd87
app_1      | 0x564a9921f274
app_1      | 0x564a98e8a138
app_1      | 0x564a98e80541
app_1      | 0x564a983c1fda, function signature specialization <Arg[1] = Dead> of App.FetchRunStatusResponse.Run.init(from: Swift.Decoder) throws -> App.FetchRunStatusResponse.Run at /build/<compiler-generated>:0
app_1      | 0x564a983c05ef, App.FetchRunStatusResponse.Run.init(from: Swift.Decoder) throws -> App.FetchRunStatusResponse.Run at /build/<compiler-generated>:0
app_1      | 0x564a983c05ef, protocol witness for Swift.Decodable.init(from: Swift.Decoder) throws -> A in conformance App.FetchRunStatusResponse.Run : Swift.Decodable in App at /build/<compiler-generated>:0
app_1      | 0x564a990c7c13
app_1      | 0x564a9921458a
app_1      | 0x564a9921f75d
app_1      | 0x564a9921ff2b
app_1      | 0x564a98e932e2
app_1      | 0x564a98e93133
app_1      | 0x564a98e9339d
app_1      | 0x564a98e9314c
app_1      | 0x564a990c7c13
app_1      | 0x564a9921458a
app_1      | 0x564a9921e3dd
app_1      | 0x564a9921f106
app_1      | 0x564a98e88a78
app_1      | 0x564a98e80211
app_1      | 0x564a983c149b, function signature specialization <Arg[1] = Dead> of App.FetchRunStatusResponse.init(from: Swift.Decoder) throws -> App.FetchRunStatusResponse at /build/<compiler-generated>:0
app_1      | 0x564a983c02d8, App.FetchRunStatusResponse.init(from: Swift.Decoder) throws -> App.FetchRunStatusResponse at /build/<compiler-generated>:0
app_1      | 0x564a983c02d8, protocol witness for Swift.Decodable.init(from: Swift.Decoder) throws -> A in conformance App.FetchRunStatusResponse : Swift.Decodable in App at /build/<compiler-generated>:0
app_1      | 0x564a990c7c13
app_1      | 0x564a9921458a
app_1      | 0x564a992141ad
app_1      | 0x564a98d3efd4, (extension in Vapor):Foundation.JSONDecoder.decode<A where A: Swift.Decodable>(_: A.Type, from: NIOCore.ByteBuffer, headers: NIOHTTP1.HTTPHeaders) throws -> A at /build/.build/checkouts/vapor/Sources/Vapor/Content/JSONCoders+Content.swift:15
app_1      | 0x564a98d3f024, protocol witness for Vapor.ContentDecoder.decode<A where A1: Swift.Decodable>(_: A1.Type, from: NIOCore.ByteBuffer, headers: NIOHTTP1.HTTPHeaders) throws -> A1 in conformance Foundation.JSONDecoder : Vapor.ContentDecoder in Vapor at /build/<compiler-generated>:0
app_1      | 0x564a98d19f77, Vapor.ClientResponse.(_ContentContainer in _7F22C431EFE320F1BBC6F926377F35A8).decode<A where A: Swift.Decodable>(_: A.Type, using: Vapor.ContentDecoder) throws -> A at /build/.build/checkouts/vapor/Sources/Vapor/Client/ClientResponse.swift:32
app_1      | 0x564a98d1a139, protocol witness for Vapor.ContentContainer.decode<A where A1: Swift.Decodable>(_: A1.Type, using: Vapor.ContentDecoder) throws -> A1 in conformance Vapor.ClientResponse.(_ContentContainer in _7F22C431EFE320F1BBC6F926377F35A8) : Vapor.ContentContainer in Vapor at /build/<compiler-generated>:0
app_1      | 0x564a98d3dc3b, (extension in Vapor):Vapor.ContentContainer.decode<A where A1: Vapor.Content>(A1.Type) throws -> A1 at /build/.build/checkouts/vapor/Sources/Vapor/Content/ContentContainer.swift:19
app_1      | 0x564a983bf65e, (1) await resume partial function for App.GithubApi.fetchRunStatus(repo: Swift.String, in: Vapor.Client) async throws -> App.RunStatus at /build/Sources/App/Common/GithubApi.swift:86
app_1      | 0x564a98e461c7
app_1      | 0x564a98e468a8
app_1      | 0x564a9918cc44
app_1      | 0x564a9918c9f2
app_1      | 0x564a99197b91
app_1      | 0x7fbca8f68608
app_1      | 0x7fbca8c67162
app_1      | 0xffffffffffffffff

Model Code

let runResponse = try response.content.decode(FetchRunStatusResponse.self)

struct FetchRunStatusResponse: Content {
    let workflow_runs:[Run]
}

extension FetchRunStatusResponse {
    struct Run: Content {
        let name:String
        let status:String
        let conclusion:String?
        let run_started_at:String?
    }
}

when I remove run_started_at key is running OK

Looks like a Codable or JSONDecoder bug.

Have you tried use snake case coding keys through custom JSONDecoder instead?

let runResponse = try response.content.decode(FetchRunStatusResponse.self, using: JSONDecoder.custom(keys: .convertFromSnakeCase))

struct FetchRunStatusResponse: Content {
    let workflowRuns:[Run]
}

extension FetchRunStatusResponse {
    struct Run: Content {
        let name:String
        let status:String
        let conclusion:String?
        let runStartedAt:String?
    }
}

Try the code you provided, it doesn't crash

Make sure you have the latest Dockerfile as well from the template. Older versions didn't install tzdata which caused crashes anytime a Date was encoded/decoded

Looking at the comparison, it is indeed not the latest. I'll replace it with the latest one to see if it still causes