{"record":{"id":"8a339d5cb2b30223","repo":"remotion-dev/remotion","slug":"onerror-was-used-but-did-not-return-an-action-fi","errorCode":null,"errorMessage":"onError was used but did not return an \"action\" field. See docs for this API on how to use onError.","messagePattern":"onError was used but did not return an \"action\" field\\. See docs for this API on how to use onError\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/parse-loop.ts","lineNumber":149,"sourceCode":"\t\t\t\t\t\titerator: state.iterator,\n\t\t\t\t\t\tlogLevel: state.logLevel,\n\t\t\t\t\t\tmode: state.mode,\n\t\t\t\t\t\tcontentLength: state.contentLength,\n\t\t\t\t\t\tseekInfiniteLoop: state.seekInfiniteLoop,\n\t\t\t\t\t\tcurrentReader: state.currentReader,\n\t\t\t\t\t\treaderInterface: state.readerInterface,\n\t\t\t\t\t\tfields: state.fields,\n\t\t\t\t\t\tsrc: state.src,\n\t\t\t\t\t\tdiscardReadBytes: state.discardReadBytes,\n\t\t\t\t\t\tprefetchCache: state.prefetchCache,\n\t\t\t\t\t\tisoState: state.iso,\n\t\t\t\t\t});\n\t\t\t\t\tstate.timings.timeSeeking += Date.now() - seekStart;\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconst err = await onError(e as Error);\n\t\t\t\tif (!err.action) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'onError was used but did not return an \"action\" field. See docs for this API on how to use onError.',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (err.action === 'fail') {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\tif (err.action === 'download') {\n\t\t\t\t\tstate.errored = e as Error;\n\t\t\t\t\tLog.verbose(\n\t\t\t\t\t\tstate.logLevel,\n\t\t\t\t\t\t'Error was handled by onError and deciding to continue.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/parse-loop.ts#L131-L167","documentation":"When a parse iteration throws and an onError callback was supplied, parseLoop awaits onError(e) and inspects the returned object. If that object has no `action` field the parser throws, because it cannot decide whether to fail or continue. The contract requires onError to return `{action: 'fail' | 'download'}`.","triggerScenarios":"Supplying an onError that returns undefined, null, `{}`, or an object missing the action key — e.g. `onError: (e) => console.error(e)` (returns undefined) or `onError: () => ({retry: true})`.","commonSituations":"Treating onError like a logging callback instead of a recovery decision function; copy-pasting from examples that omit the return; migration from an older API shape.","solutions":["Make onError return an object with action: `{action: 'fail'}` to re-throw, or `{action: 'download'}` to continue parsing.","If you only want to log, return `{action: 'fail'}` after logging so the original error still propagates.","Add a TypeScript annotation `onError: ParseMediaOnError` so a missing action is caught at compile time.","Read the media-parser onError docs for the full return contract."],"exampleFix":"// before\nawait parseMedia({src, onError: (e) => console.error(e), fields: {}});\n\n// after\nawait parseMedia({\n  src,\n  onError: (e) => {\n    console.error(e);\n    return {action: 'fail'};\n  },\n  fields: {},\n});","handlingStrategy":"type-guard","validationCode":"// Validate your onError returns the right shape before passing it in\nfunction makeOnError(log: (e: Error) => void) {\n  return (e: Error): {action: 'fail' | 'download'} => {\n    log(e);\n    return {action: 'fail'};\n  };\n}","typeGuard":"import type {ParseMediaOnError} from '@remotion/media-parser';\nconst isOnErrorResult = (v: unknown): v is {action: 'fail' | 'download'} =>\n  typeof v === 'object' && v !== null &&\n  (v as any).action === 'fail' || (v as any).action === 'download';","tryCatchPattern":"// Not applicable — this error IS the result of a bad onError contract.\n// Fix: ensure onError always returns {action: 'fail' | 'download'}.\nawait parseMedia({\n  src,\n  onError: (e) => { console.error(e); return {action: 'fail'}; },\n  fields: {},\n});","preventionTips":["Always return {action: 'fail'} or {action: 'download'} from onError.","Type onError as ParseMediaOnError so a missing action is a compile error.","If you only log, still return {action: 'fail'} to propagate the original error.","Read the onError docs for the full recovery contract."],"tags":["api-misuse","onerror","media-parser","typescript"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}