{"id":"c9a4c0ceda70fdfb","repo":"jestjs/jest","slug":"invalid-return-value-process-or-and-proc","errorCode":null,"errorMessage":"● Invalid return value:\n  `process()` or/and `processAsync()` method of code transformer found at \n  \"${slash(transformPath)}\" \n  should return an object or a Promise resolving to an object. The object \n  must have `code` property with a string of processed code.\n\n  This error may be caused by a breaking change in Jest 28:\n  https://jest-archive-august-2023.netlify.app/docs/28.x/upgrading-to-jest28#transformer\n  Code Transformation Documentation:\n  https://jestjs.io/docs/code-transformation\n","messagePattern":"● Invalid return value:\n  `process\\(\\)` or/and `processAsync\\(\\)` method of code transformer found at \n  \"(.+?)\" \n  should return an object or a Promise resolving to an object\\. The object \n  must have `code` property with a string of processed code\\.\n\n  This error may be caused by a breaking change in Jest 28:\n  https://jest-archive-august-2023\\.netlify\\.app/docs/28\\.x/upgrading-to-jest28#transformer\n  Code Transformation Documentation:\n  https://jestjs\\.io/docs/code-transformation\n","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-transform/src/ScriptTransformer.ts","lineNumber":407,"sourceCode":"    content: string,\n    transformer: Transformer | undefined,\n    shouldCallTransform: boolean,\n    options: ReducedTransformOptions,\n    processed: TransformedSource | null,\n    sourceMapPath: string | null,\n  ): TransformResult {\n    let transformed: TransformedSource = {\n      code: content,\n      map: null,\n    };\n\n    if (transformer && shouldCallTransform) {\n      if (processed != null && typeof processed.code === 'string') {\n        transformed = processed;\n      } else {\n        const transformPath = this._getTransformPath(filename);\n        invariant(transformPath);\n        throw new Error(makeInvalidReturnValueError(transformPath));\n      }\n    }\n\n    if (transformed.map == null || transformed.map === '') {\n      try {\n        //Could be a potential freeze here.\n        //See: https://github.com/jestjs/jest/pull/5177#discussion_r158883570\n        const inlineSourceMap = sourcemapFromSource(transformed.code);\n        if (inlineSourceMap) {\n          transformed.map = inlineSourceMap.toObject() as FixedRawSourceMap;\n        }\n      } catch {\n        const transformPath = this._getTransformPath(filename);\n        invariant(transformPath);\n        console.warn(makeInvalidSourceMapWarning(filename, transformPath));\n      }\n    }\n","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-transform/src/ScriptTransformer.ts#L389-L425","documentation":"Thrown by `_buildTransformResult` (ScriptTransformer.ts:401-408) via `makeInvalidReturnValueError` when a transformer's `process`/`processAsync` was called and returned a non-null value, but that value's `code` property is not a string. The transformer contract (`TransformedSource`) requires `{ code: string, map?: ... }`; returning the source string directly, an array, or an object without `code` triggers this.","triggerScenarios":"A transformer that `return compile(source)` (string) instead of `return { code: compile(source) }`; returning `{ transformed: ... }` (wrong key); returning a Promise resolving to a string; returning `undefined` from a branch (`if (...) return;`).","commonSituations":"The headline Jest 28 upgrade breakage called out in the error text: pre-28 transformers returned `{ code, map }` but some returned just the code string; authors following an outdated guide; async transformer forgetting to await the compile and returning `Promise<string>`.","solutions":["Always return `{ code: <string>, map?: <sourceMap> }` from `process`/`processAsync`.","Read the linked Jest 28 upgrade guide and the `TransformedSource` type from `@jest/transform`.","Add a TypeScript return-type annotation (`: TransformedSource`) so the shape is checked at compile time.","For async transformers, `return { code: await compile(source) }` - never return the bare string promise."],"exampleFix":"// before\nmodule.exports = {\n  process(source) { return compile(source); }, // returns a string\n};\n// after\nmodule.exports = {\n  process(source) { return { code: compile(source) }; },\n};","handlingStrategy":"type-guard","validationCode":"// Unit-test your transformer's return shape\nconst out = transformer.process('let x', 'fake.js', {});\nif (out == null || typeof out.code !== 'string')\n  throw new Error('process() must return { code: string }');","typeGuard":"const isTransformedSource = (v: any): boolean =>\n  v != null && typeof v === 'object' && typeof v.code === 'string';","tryCatchPattern":null,"preventionTips":["Annotate `process(source, filename, options): TransformedSource` so the compiler enforces the shape.","Always return `{ code, map? }` - never a bare string or Promise<string>.","For async transformers, `return { code: await compile(src) }`."],"tags":["jest-transform","transformer","jest-28-upgrade","user-error"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}