// Forms · Drive · Apps Script

Move uploaded files into a Drive folder in Google Forms.

How to use Apps Script to automatically move file-upload responses from a Google Form into a specific Drive folder, using DriveApp.getFileById() to resolve the ID strings that itemResponse.getResponse() actually returns.

I want to move files uploaded through a Google Form into a specific Drive folder automatically, instead of leaving them scattered in the form's default upload location.

The script

copy · paste · trigger
moveUploadedFiles.gs
Apps Script
// Trigger: Form submit — moves uploaded files to a target folder
// Set TARGET_FOLDER_ID to the destination Drive folder's ID
var TARGET_FOLDER_ID = 'YOUR_FOLDER_ID_HERE';

function onFormSubmit(e) {
  var folder = DriveApp.getFolderById(TARGET_FOLDER_ID);
  var items = e.response.getItemResponses();

  for (var i = 0; i < items.length; i++) {
    var item = items[i];
    if (item.getItem().getType() === FormApp.ItemType.FILE_UPLOAD) {
      var fileIds = item.getResponse(); // always an array of strings
      for (var j = 0; j < fileIds.length; j++) {
        var file = DriveApp.getFileById(fileIds[j]);
        file.moveTo(folder);
      }
    }
  }
}

Need a variant? Gnaw writes a custom version from one sentence — fields, triggers, edge cases handled.

Walkthrough

Why getResponse() breaks your first attempt

The mental model most people arrive with: the form gives you a File object, you call moveTo() on it, done. What actually comes back from itemResponse.getResponse() on a FILE_UPLOAD item is an array of Drive file ID strings. Not File objects. Strings. Even if only one file was uploaded, you get a one-element array like ["1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs"].

That ID string is just text. Calling .moveTo() on a string throws a TypeError immediately, which is why the trigger appears to fire but nothing moves. The fix is a single hop through DriveApp.getFileById() to get a proper File object before you touch it.

The first time I hit this, I spent twenty minutes checking folder permissions before reading the error message carefully. 'Cannot call method moveTo of undefined' is the giveaway that you're still holding a string.

Installing the submit trigger

Open your form in Google Drive, then open the bound Apps Script project via Extensions > Apps Script. Paste the script and replace YOUR_FOLDER_ID_HERE with the real folder ID. You can pull that ID from the folder's URL: it's the long alphanumeric string after /folders/.

You cannot use the simple onFormSubmit name as an installable trigger — that name is reserved for simple triggers, which do not receive the event object with response data. In the Apps Script editor go to Triggers (the clock icon), click Add Trigger, choose onFormSubmit as the function, choose From form as the event source, and On form submit as the event type. This creates an installable trigger that does pass the full event.

Once the trigger is saved, submit a test response with a file attached. Check the target folder; the file should appear within a few seconds. If it does not, open Executions in the left sidebar to read the error log.

Handling multiple uploads and renaming on arrival

The inner loop over fileIds handles forms where the upload question allows multiple files — the quota for FILE_UPLOAD items is up to 10 files per submission. If your form only allows one file, the loop still works fine; it just runs once.

If you want to rename the file on arrival (for example, to prefix the respondent's email), grab the email from e.response.getRespondentEmail() and call file.setName() before moveTo(). Order matters: setName() first, then moveTo(), otherwise you end up renaming the file in the original location and then moving it, which works but reads oddly in the audit trail.

One practical limit: moveTo() requires that the script runner has edit access to both the file's current parent folder (the form's upload bucket) and the destination folder. If you're running this under a service account or a shared-drive-restricted context, that permission check is where it will fail silently.

Want a custom version?

Describe your sheet and the rule you want. Gnaw writes the Apps Script — fields, triggers, edge cases — in one shot.

FAQ

4 questions
Why does itemResponse.getResponse() return an array even when only one file was uploaded?
FILE_UPLOAD items support multiple file uploads in a single response, so the API always returns an array of ID strings regardless of how many files were actually submitted. Treat it as an array even in the single-file case.
The trigger fires but files are not moving. How do I debug it?
Open the Apps Script editor and check Executions in the left sidebar. Look for a failed run and expand the error. The most common causes are: a TypeError from calling moveTo() on a raw string (missing the DriveApp.getFileById() step), or a permissions error because the script runner lacks edit access to the destination folder.
Does moveTo() make a copy or actually move the file?
It moves the file — no copy is created and no extra Drive quota is consumed. The file ID stays the same after the move; only its parent folder changes.
Can I route files to different folders based on which question they answered?
Yes. Call item.getItem().getTitle() inside the loop to get the question title, then use a lookup object or a series of if-statements to map question titles to folder IDs. Just call DriveApp.getFolderById() with the appropriate ID for each item before the inner fileIds loop.