{"record":{"id":"ce307a087743fafb","repo":"remotion-dev/remotion","slug":"name-must-be-between-0-and-1-but-got-json","errorCode":null,"errorMessage":"\"${name}\" must be between 0 and 1, but got ${JSON.stringify(value)}","messagePattern":"\"(.+?)\" must be between 0 and 1, but got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/effects/src/skew.ts","lineNumber":92,"sourceCode":"});\n\nconst assertOptionalUvCoordinate = (value: unknown, name: string): void => {\n\tif (value === undefined) {\n\t\treturn;\n\t}\n\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 validateUvCoordinate = (value: number, name: string): void => {\n\tif (value < 0 || value > 1) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be between 0 and 1, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateAngle = (value: number, name: string): void => {\n\tif (Math.abs(value) >= MAX_ABSOLUTE_ANGLE) {\n\t\tthrow new TypeError(\n\t\t\t`\"${name}\" must be greater than -${MAX_ABSOLUTE_ANGLE} and less than ${MAX_ABSOLUTE_ANGLE}, but got ${JSON.stringify(value)}`,\n\t\t);\n\t}\n};\n\nconst validateSkewParams = (params: SkewParams): void => {\n\tassertEffectParamsObject(params, 'Skew');\n\tassertOptionalFiniteNumber(params.x, 'x');\n\tassertOptionalFiniteNumber(params.y, 'y');\n\tassertOptionalUvCoordinate(params.origin, 'origin');","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/skew.ts#L74-L110","documentation":"The skew() effect's validateUvCoordinate helper checks each component of the resolved origin tuple. Both components must be within the inclusive range [0, 1] because they specify a position in UV (normalized) coordinate space. Passing an origin component outside this range throws this TypeError.","triggerScenarios":"Calling skew({ origin: [1.5, 0.5] }) (first component > 1), skew({ origin: [0.5, -0.2] }) (second component < 0), or skew({ origin: [2, 2] }). This fires after the tuple-shape check passes, so the value is a valid [number, number] but one or both components are out of [0, 1].","commonSituations":"Passing pixel coordinates instead of normalized UV coordinates; computing origin from a formula that can exceed [0, 1]; confusing UV coordinates (0–1) with pixel coordinates or percentage values (0–100); animation interpolations that overshoot their target range.","solutions":["Ensure both origin components are between 0 and 1 inclusive (0 = left/top edge, 0.5 = center, 1 = right/bottom edge).","If you have pixel coordinates, convert them: originX_pixels / width, originY_pixels / height.","Clamp interpolated values: Math.min(1, Math.max(0, value)).","Remember UV coordinates are normalized, not percentages — 50% is 0.5, not 50."],"exampleFix":"// before — pixel coordinates passed as UV\nskew({ x: 20, y: 10, origin: [320, 180] })\n\n// after — converted to normalized UV coordinates (for a 640x360 frame)\nconst [w, h] = [640, 360];\nskew({ x: 20, y: 10, origin: [320 / w, 180 / h] })\n// or simply use the default center\nskew({ x: 20, y: 10 })","handlingStrategy":"validation","validationCode":"// Validate and clamp origin components to [0, 1] before calling skew\nfunction normalizeOrigin(origin: [number, number]): [number, number] {\n  return origin.map((v) => Math.min(1, Math.max(0, v))) as [number, number];\n}\n\n// Or validate strictly:\nfunction assertValidOrigin(origin: [number, number]): void {\n  for (const [i, v] of origin.entries()) {\n    if (v < 0 || v > 1) {\n      throw new Error(`origin[${i}] must be between 0 and 1, got ${v}`);\n    }\n  }\n}\n\nassertValidOrigin(rawOrigin);\nskew({ x: 20, origin: rawOrigin });","typeGuard":"const isValidUvTuple = (v: readonly [number, number]): boolean =>\n  v[0] >= 0 && v[0] <= 1 && v[1] >= 0 && v[1] <= 1;\n\n// Usage:\nif (isNumberTuple(rawOrigin) && isValidUvTuple(rawOrigin)) {\n  skew({ x: 20, origin: rawOrigin });\n}","tryCatchPattern":"try {\n  skew({ x: 20, y: 0, origin: rawOrigin });\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('between 0 and 1')) {\n    // Clamp to valid range and retry\n    const clamped = rawOrigin.map((v) => Math.min(1, Math.max(0, v)));\n    skew({ x: 20, y: 0, origin: clamped as [number, number] });\n  } else {\n    throw e;\n  }\n}","preventionTips":["UV coordinates are normalized: 0 = edge, 0.5 = center, 1 = opposite edge.","Convert pixel coordinates to UV before passing: x_pixels / width, y_pixels / height.","Clamp interpolated or computed values to [0, 1] before passing to skew().","Do not pass percentages (0–100) or pixel coordinates as UV coordinates."],"tags":["validation","typescript","skew","parameters","uv-coordinates"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}