{"record":{"id":"4c8517d62d8a523e","repo":"remotion-dev/remotion","slug":"name-must-be-an-integer-but-got-json-strin","errorCode":null,"errorMessage":"\"${name}\" must be an integer, but got ${JSON.stringify(value)}","messagePattern":"\"(.+?)\" must be an integer, but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/noise-displacement.ts","lineNumber":198,"sourceCode":"});\n\nconst assertRequiredUvCoordinate = (value: unknown, name: string): void => {\n\tif (\n\t\t!Array.isArray(value) ||\n\t\tvalue.length !== 2 ||\n\t\tvalue.some((item) => typeof item !== 'number' || !Number.isFinite(item))\n\t) {\n\t\tthrow new TypeError(`\"${name}\" must be a [number, number] tuple`);\n\t}\n};\n\nconst assertOptionalIntegerNumber = (value: unknown, name: string): void => {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\n\tif (!Number.isInteger(value)) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be an integer, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validatePositive = (value: number, name: string): void => {\n\tif (value <= 0) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than 0, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateMax = (value: number, max: number, name: string): void => {\n\tif (value > max) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be <= ${max}, but got ${JSON.stringify(value)}`,\n\t\t);","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/noise-displacement.ts#L180-L216","documentation":"The noiseDisplacement() effect's optional `passes` prop (number of source samples along the displacement path) must be an integer if provided. assertOptionalIntegerNumber throws this TypeError when passes is defined but not a whole number. The default is 6 and the maximum is 12.","triggerScenarios":"Calling noiseDisplacement({ passes: 6.5 }), noiseDisplacement({ passes: 3.1 }), or noiseDisplacement({ passes: '6' }) after the finite-number check. Any defined value where Number.isInteger returns false triggers it.","commonSituations":"Interpolating passes from a slider that allows fractional values; computing passes dynamically with division that yields non-integer results; deserializing passes as a float from config; confusion with other props that accept decimals.","solutions":["Use a whole number for passes: noiseDisplacement({ passes: 6 }).","If computing dynamically, round explicitly: passes: Math.round(computedValue).","Omit passes to use the default of 6.","Ensure the value is between 1 and 12 (inclusive)."],"exampleFix":"// before\nnoiseDisplacement({ center: [0.5, 0.5], radius: 0.5, passes: 6.5 })\n\n// after\nnoiseDisplacement({ center: [0.5, 0.5], radius: 0.5, passes: 6 })\n// or\nnoiseDisplacement({ center: [0.5, 0.5], radius: 0.5, passes: Math.round(value) })","handlingStrategy":"validation","validationCode":"// Validate passes before calling noiseDisplacement()\nif (params.passes !== undefined && !Number.isInteger(params.passes)) {\n  throw new Error(`passes must be an integer, got ${params.passes}`);\n}\nconst result = noiseDisplacement(params);","typeGuard":"const isValidPasses = (p: unknown): boolean =>\n  p === undefined || (typeof p === 'number' && Number.isInteger(p));","tryCatchPattern":null,"preventionTips":["Use whole numbers for passes — it represents discrete shader samples.","When animating passes, round with Math.round() before passing.","Remember passes must be an integer between 1 and 12."],"tags":["validation","typescript","noise-displacement","params","typeerror"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}