{"record":{"id":"5221221beb1e8973","repo":"heygen-com/hyperframes","slug":"validateconfig-config-step-functions-execution","errorCode":null,"errorMessage":"[validateConfig] config: Step Functions execution input is not JSON-serializable: ${err instanceof Error ? err.message : String(err)}","messagePattern":"\\[validateConfig\\] config: Step Functions execution input is not JSON-serializable: (.+?)","errorType":"validation","errorClass":"InvalidConfigError","httpStatus":null,"severity":"error","filePath":"packages/aws-lambda/src/sdk/validateConfig.ts","lineNumber":55,"sourceCode":"/**\n * Validate that the serialized Step Functions execution input fits inside the\n * 256 KiB Standard-workflow cap. Measured in UTF-8 bytes (the format Step\n * Functions uses on the wire) — JS strings count UTF-16 code units, which\n * under-reports for any multi-byte character.\n *\n * Throws {@link InvalidConfigError} with a clear message naming the actual\n * byte count, the cap, and a pointer to the \"working with large variables\"\n * docs section, so users hit the limit at the SDK boundary with actionable\n * guidance instead of as a `States.DataLimitExceeded` 50 ms into the\n * execution.\n */\n// fallow-ignore-next-line complexity\nexport function validateStepFunctionsInputSize(input: unknown): void {\n  let serialized: string | undefined;\n  try {\n    serialized = JSON.stringify(input);\n  } catch (err) {\n    throw new InvalidConfigError(\n      \"config\",\n      `Step Functions execution input is not JSON-serializable: ${err instanceof Error ? err.message : String(err)}`,\n    );\n  }\n  if (serialized === undefined) {\n    throw new InvalidConfigError(\n      \"config\",\n      \"Step Functions execution input is not JSON-serializable (JSON.stringify returned undefined). \" +\n        \"Check that all fields, including config.variables, are plain JSON values.\",\n    );\n  }\n  const byteLength = Buffer.byteLength(serialized, \"utf8\");\n  if (byteLength > MAX_STEP_FUNCTIONS_INPUT_BYTES) {\n    throw new InvalidConfigError(\n      \"config\",\n      `Step Functions execution input is ${byteLength} bytes, which exceeds the ` +\n        `${MAX_STEP_FUNCTIONS_INPUT_BYTES}-byte (256 KiB) limit for Standard workflows. ` +\n        `Variables are for typed data (strings, numbers, structured records); media assets ` +","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/aws-lambda/src/sdk/validateConfig.ts#L37-L73","documentation":"Thrown as an InvalidConfigError by validateStepFunctionsInputSize when JSON.stringify(input) throws — meaning the Step Functions execution input contains a value that is not JSON-serializable. The most common cause is config.variables holding a circular reference, a BigInt, a function, or a Symbol-keyed structure. validateStepFunctionsInputSize is called by renderToLambda after assembling { ProjectS3Uri, Config, … } so the offending value is typically inside Config (the variables map). Catching it here surfaces the cause at the SDK boundary instead of as an opaque serialization failure inside the SFN wire layer.","triggerScenarios":"config.variables includes a circular object (e.g. a DOM node or a class instance with back-references); a BigInt value; a function reference; a Symbol. The stringify of the whole input object throws.","commonSituations":"Passing a class instance (a Date subclass, a Moment object) instead of an ISO string; a variables map that includes the request/response object itself; a BigInt counter; an object with a self-referential parent pointer.","solutions":["Inspect config.variables for non-JSON values: replace Date objects with .toISOString(), BigInt with String(), class instances with plain objects.","Break circular references before the call (e.g. structuredClone with a replacer, or JSON.stringify with a custom replacer that detects cycles).","Run JSON.stringify(JSON.parse(JSON.stringify(vars))) as a sanitization pre-step if the data is mostly-plain.","Add a unit test that serializes the variables you intend to send."],"exampleFix":"// before\nconfig.variables = { user, req }; // req is circular\n\n// after\nconfig.variables = { userId: user.id, path: req.path }; // plain values only","handlingStrategy":"validation","validationCode":"function assertSerializable(value: unknown): void {\n  try {\n    JSON.stringify(value);\n  } catch (err) {\n    throw new Error(`input is not JSON-serializable: ${(err as Error).message}`);\n  }\n}\n// call before validateStepFunctionsInputSize / renderToLambda","typeGuard":"const isPlainJsonValue = (v: unknown): boolean => {\n  if (v === null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') return true;\n  if (Array.isArray(v)) return v.every(isPlainJsonValue);\n  if (typeof v === 'object') return Object.values(v).every(isPlainJsonValue);\n  return false;\n};","tryCatchPattern":null,"preventionTips":["Keep config.variables to plain JSON types (string/number/boolean/object/array).","Convert Date/Moment/BigInt to primitives before assignment.","Add a unit test that JSON.stringify's the variables you send."],"tags":["validation","step-functions","config","serialization","json"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}