{"record":{"id":"52f33ade5f66d1cc","repo":"heygen-com/hyperframes","slug":"validateconfig-config-step-functions-execution-52f33a","errorCode":null,"errorMessage":"[validateConfig] config: Step Functions execution input is not JSON-serializable (JSON.stringify returned undefined). Check that all fields, including config.variables, are plain JSON values.","messagePattern":"\\[validateConfig\\] config: Step Functions execution input is not JSON-serializable \\(JSON\\.stringify returned undefined\\)\\. Check that all fields, including config\\.variables, are plain JSON values\\.","errorType":"validation","errorClass":"InvalidConfigError","httpStatus":null,"severity":"error","filePath":"packages/aws-lambda/src/sdk/validateConfig.ts","lineNumber":61,"sourceCode":" * 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 ` +\n        `(images, audio, video) should be passed as URL references the composition resolves ` +\n        `at render time, not inlined as base64. See ${LARGE_VARIABLES_DOCS_URL} for the ` +\n        `URL-your-assets convention.`,\n    );\n  }\n}","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/aws-lambda/src/sdk/validateConfig.ts#L43-L79","documentation":"Thrown as an InvalidConfigError by validateStepFunctionsInputSize when JSON.stringify(input) returns undefined rather than throwing. Per the JS spec, JSON.stringify returns undefined (not throws) when the top-level value is a function, a Symbol, or undefined itself. This is distinct from error 50 (which fires when stringify throws on nested bad values). The message points specifically at config.variables because that is the usual source of a top-level non-serializable value when the input wrapper is assembled.","triggerScenarios":"The entire input object, or the value fed to stringify, is a function or Symbol; config.variables was set to a function or undefined instead of an object. Less common than error 50 because the wrapper { ProjectS3Uri, Config, … } is normally a plain object — this fires when the wrapper itself is replaced or when a custom serializer is in play.","commonSituations":"A middleware that replaces the input with a function; config.variables assigned to undefined explicitly; a Symbol used as the top-level input; a bug where input = someFunction instead of input = { Config: someFunction }.","solutions":["Ensure the object passed to validateStepFunctionsInputSize is a plain object literal, not a function/Symbol/undefined.","Confirm config.variables is an object (Record<string, …>), not undefined or a function reference.","Add a typeof input === 'object' && input !== null guard before validation.","Log the input's type before the call to spot a function/Symbol top-level."],"exampleFix":"// before\nvalidateStepFunctionsInputSize(config.variables?.toString);\n// toString is a function -> stringify returns undefined\n\n// after\nvalidateStepFunctionsInputSize({ ...input, Config: { ...config, variables: vars } });","handlingStrategy":"validation","validationCode":"function assertPlainObjectInput(input: unknown): asserts input is Record<string, unknown> {\n  if (input === undefined || input === null || typeof input !== 'object' || Array.isArray(input)) {\n    throw new Error('Step Functions input must be a plain object');\n  }\n  const serialized = JSON.stringify(input);\n  if (serialized === undefined) throw new Error('input serializes to undefined');\n}","typeGuard":"const isSerializableObject = (v: unknown): boolean => {\n  if (v === null || typeof v !== 'object' || Array.isArray(v)) return false;\n  return JSON.stringify(v) !== undefined;\n};","tryCatchPattern":null,"preventionTips":["Always wrap the input in a plain object literal { … }.","Ensure config.variables is an object, never a function or undefined.","Sanitize variables with a JSON round-trip (JSON.parse(JSON.stringify(vars))) before passing."],"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"}