createFiles bug

Topic summary

A user encounters an issue where file URLs are not immediately available after calling the fileCreate mutation. When getFilesByIds is called right after file creation, the response lacks URLs. However, wrapping the query in setTimeout successfully retrieves the URLs.

Root Cause:
The file creation process is asynchronous—files need processing time before URLs become available.

Workaround Suggested:

  1. Create the files via fileCreate mutation
  2. Implement a polling mechanism to periodically fetch file details
  3. Continue with the rest of the code once URLs are available

The delay from setTimeout gives files enough time to be processed and generate URLs.

User Concern:
The original poster expresses frustration that this behavior seems like a significant issue, noting it wasn’t documented and questioning whether the waiting process should be handled server-side instead.

Status: The discussion remains open with a functional workaround but unresolved concerns about API design and documentation.

Summarized with AI on November 14. AI used: claude-sonnet-4-5-20250929.

When I’ve created files I want to save links. But if I request files immediately, I don’t have urls in the response. But if I use setTimeut, I get them!!!

There’s the code:

const createFiles = async (files, stagedTargets, graphql) => {
    const response = await graphql(`
        mutation fileCreate($files: [FileCreateInput!]!) {
            fileCreate(files: $files) {
                files {
                    fileErrors {
                        code
                        details
                        message
                    }
                    ... on MediaImage {
                        id
                    }
                    ... on GenericFile {
                        id
                    }
                    ... on Video {
                        id
                    }
                }
                userErrors {
                    field
                    message
                }
            }
        }
    `, {
        variables: {
            files: prepareFilesToCreate(stagedTargets, files),
        }
    });

    const result = await response.json();

    return {
        response: result,
        errors: result.data.fileCreate.userErrors,
    }
}
const getFilesByIds = async (files, graphql) => {
    try {
        const response = await graphql(`
            query ($ids: [ID!]!) {
                nodes(ids: $ids) {
                    __typename
                    ... on GenericFile {
                        id
                        url
                        fileErrors {
                            code
                            details
                            message
                        }
                    }
                    ... on MediaImage {
                        id
                        fileErrors {
                            code
                            details
                            message
                        }
                        image {
                            url
                        }
                    }
                }
            }
        `, {
            variables: {
                ids: files.map((file) => file.id),
            }
        });

        const result = await response.json();

        return {
            response: result.data.nodes,
            errors: result.errors,
        }
    } catch (e) {
        return {
            errors: [e?.message || 'Files getting error']
        }
    }
}

it doesn’t work:

  const newFiles = await getFilesByIds(createFilesResponse.data.fileCreate.files, graphql);

  console.log('newFiles', newFiles.response);
  console.log('newFiles2', newFiles.response.map((file) => file.image));
  console.log('errors', newFiles.errors);

But it works:

setTimeout(async () => {
  const newFiles = await getFilesByIds(createFilesResponse.data.fileCreate.files, graphql);

  console.log('newFiles', newFiles.response);
  console.log('newFiles2', newFiles.response.map((file) => file.image));
  console.log('errors', newFiles.errors);
}, 5000)

I guess createdFiles shoud set links before request, not after…

And i’m using second request because fileCreate returns nothing

HI EvilGranny,

Your observation is correct. The file creation process is asynchronous, meaning that the file might not be immediately available after the createFiles function is called. This is why when you immediately call getFilesByIds, the URLs are not available yet. However, when you delay the execution of getFilesByIds by using setTimeout, the files have enough time to be processed and their URLs become available.

A common way to handle this is to use some kind of polling mechanism:

  1. Create the files.
  2. Periodically fetch the file details until the URLs are available.
  3. Proceed with the rest of your code.

Hope this helps,

1 Like

Yeah… It helps, thank you, but that’s looks like very big issue. First of all it shouldn’t work this way and it wasn’t described in the docs…

I believe, waiting process should be on your side