{"record":{"id":"f2fb4cc232832045","repo":"HeyPuter/puter","slug":"bad-request-f2fb4c","errorCode":"bad_request","errorMessage":"`file` is required","messagePattern":"`file` is required","errorType":"validation","errorClass":"HttpError","httpStatus":400,"severity":"error","filePath":"src/backend/drivers/ai-speech2txt/providers/SpeechToTextProvider.ts","lineNumber":67,"sourceCode":"\n    getReportedCosts(): Record<string, unknown>[] {\n        return [];\n    }\n\n    /** The authenticated caller, or a 401 if the request carries none. */\n    protected requireActor(): Actor {\n        const actor = Context.get('actor') as Actor | undefined;\n        if (!actor)\n            throw new HttpError(401, 'Authentication required', {\n                legacyCode: 'unauthorized',\n            });\n        return actor;\n    }\n\n    /** Reject the call unless the caller supplied audio. */\n    protected requireFile(args: ITranscribeArgs): void {\n        if (!args.file)\n            throw new HttpError(400, '`file` is required', {\n                legacyCode: 'bad_request',\n            });\n    }\n}\n","sourceCodeStart":49,"sourceCodeEnd":72,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-speech2txt/providers/SpeechToTextProvider.ts#L49-L72","documentation":"The base provider's requireFile(args) rejects when args.file is falsy. The OpenAI provider calls this.requireFile(args) before loadFileInput, so a missing file never reaches file resolution (which has its own 'Missing file input' 400). file is the STT equivalent of audio — a path, data URL, web URL, or {path/uid/uuid}.","triggerScenarios":"Calling transcribe({ model }) with no file; file: null / undefined / ''; a field renamed from audio to file mid-migration leaving the field empty.","commonSituations":"UI submit before an audio file is attached; field rename from audio to file leaving the field empty; an empty upload payload.","solutions":["Provide file as a data URL, an FS path string, { path }, { uid } / { uuid }, or an accepted web URL.","Validate a non-empty file reference client-side before the request."],"exampleFix":"// before\ndriver.transcribe({ model: 'whisper-1' })\n// after\ndriver.transcribe({ file: '/alice/sample.mp3', model: 'whisper-1' })","handlingStrategy":"validation","validationCode":"if (!args.file) throw new Error('`file` is required');","typeGuard":"function hasFile(a): a is { file: string | Record<string, unknown> } {\n  return Boolean(a && (typeof a.file === 'string' || (a.file && typeof a.file === 'object')));\n}","tryCatchPattern":null,"preventionTips":["Disable submit until an audio file is selected.","Send audio as a data URL to avoid empty fields.","Watch for the audio -> file field rename when migrating."],"tags":["validation","input","speech2txt"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}