{"record":{"id":"ed29181a97328c00","repo":"ory/hydra","slug":"cookiex-cannot-marshal-cookie-value","errorCode":null,"errorMessage":"cookiex: cannot marshal cookie value","messagePattern":"cookiex: cannot marshal cookie value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/cookiex/cookiex.go","lineNumber":134,"sourceCode":"\n// envelope wraps the JSON payload with the seal time so decoding can enforce\n// the max age.\ntype envelope struct {\n\tIssuedAt int64           `json:\"iat\"`\n\tValues   json.RawMessage `json:\"v\"`\n}\n\n// aad binds a ciphertext to this codec's purpose and the cookie name, so a\n// sealed value cannot be replayed as a different cookie or in a different\n// context, even under the same key.\nfunc (c *Codec[T]) aad(name string) []byte {\n\treturn []byte(aadPrefix + \"|\" + c.purpose + \"|\" + name)\n}\n\nfunc (c *Codec[T]) seal(name string, value T) (string, error) {\n\tpayload, err := json.Marshal(value)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"cookiex: cannot marshal cookie value\")\n\t}\n\tplaintext, err := json.Marshal(envelope{IssuedAt: c.now().Unix(), Values: payload})\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"cookiex: cannot marshal envelope\")\n\t}\n\ta, err := aead.New(c.keys[0])\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"cookiex: cannot create AEAD\")\n\t}\n\t// The nonce is prepended to the ciphertext. AEADs that manage the nonce\n\t// internally report a nonce size of zero, so this also covers them.\n\tnonce := make([]byte, a.NonceSize())\n\tif _, err := rand.Read(nonce); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"cookiex: cannot generate nonce\")\n\t}\n\tsealed := a.Seal(nonce, nonce, plaintext, c.aad(name))\n\treturn formatPrefix + base64.RawURLEncoding.EncodeToString(sealed), nil\n}","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/cookiex/cookiex.go#L116-L152","documentation":"Returned by Codec.seal when json.Marshal of the caller's cookie value (type T) fails. The generic payload T contains a value that cannot be represented as JSON — e.g. a channel, func, cyclic reference, or unsupported map key type.","triggerScenarios":"Thrown at oryx/cookiex/cookiex.go:134 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Make the cookie payload type T fully JSON-serializable (no funcs, channels, cycles, invalid map keys)","Implement json.Marshaler on the offending type or store an ID/reference instead of the complex object","Log the wrapped marshal error to identify which field fails serialization"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}