twentyhq/twenty · error · Error
completeFileUpload mutation did not return a file id
Error message
completeFileUpload mutation did not return a file id
What it means
After the media bytes are uploaded to the presigned URL, the flow calls the metadata `completeFileUpload` mutation with the `fileId` to finalize the upload and receive the canonical file id. If `mutationResult.completeFileUpload?.id` is undefined, finalization did not return an id and the flow throws. This typically means the upload never completed server-side or the fileId is unknown to the server.
Source
Thrown at packages/twenty-apps/public/call-recorder/src/logic-functions/flows/import-call-recording-media.util.ts:356
};
const completeFileUpload = async ({
metadataClient,
fileId,
}: {
metadataClient: InstanceType<typeof MetadataApiClient>;
fileId: string;
}): Promise<string> => {
const mutationResult = await metadataClient.mutation({
completeFileUpload: {
__args: { fileId },
id: true,
},
});
const uploadedFileId = mutationResult.completeFileUpload?.id;
if (isUndefined(uploadedFileId)) {
throw new Error('completeFileUpload mutation did not return a file id');
}
return uploadedFileId;
};
const parseContentLengthBytes = (
headerValue: string | null,
): number | undefined => {
if (!isNonEmptyString(headerValue)) {
return undefined;
}
const parsedBytes = Number(headerValue.trim());
return Number.isFinite(parsedBytes) && parsedBytes >= 0
? parsedBytes
: undefined;
};View on GitHub (pinned to 1f5dd2bbd2)
Solutions
- Confirm the upstream PUT to `uploadUrl` succeeded (capture its status) before calling `completeFileUpload`.
- Ensure the `fileId` passed in is exactly the one returned by the preceding `createFileUpload` call in this same flow.
- Log `mutationResult` in full (including `errors`) to surface the server's reason for omitting the id.
- If finalization is transiently failing, retry the `completeFileUpload` mutation with backoff before aborting the whole import.
Example fix
// before
const uploadedFileId = mutationResult.completeFileUpload?.id;
if (isUndefined(uploadedFileId)) {
throw new Error('completeFileUpload mutation did not return a file id');
}
// after — include the fileId and any server errors in the message
const uploadedFileId = mutationResult.completeFileUpload?.id;
if (isUndefined(uploadedFileId)) {
throw new Error(
`completeFileUpload mutation did not return a file id for fileId=${fileId}; server errors: ${JSON.stringify(mutationResult.errors ?? [])}`,
);
} Defensive patterns
Strategy: validation
Validate before calling
// Confirm the PUT to the presigned URL succeeded before completing.
if (!uploadOk) {
throw new Error(`Cannot completeFileUpload for ${fileId}: upstream PUT did not succeed`);
} Type guard
const hasCompletedFileId = (r: unknown): r is { completeFileUpload: { id: string } } =>
typeof r === 'object' &&
r !== null &&
typeof (r as any).completeFileUpload?.id === 'string'; Try / catch
async function completeWithRetry(metadataClient: any, fileId: string, attempts = 3): Promise<string> {
let lastErr: unknown;
for (let i = 0; i < attempts; i++) {
try {
const r = await metadataClient.mutation({ completeFileUpload: { __args: { fileId }, id: true } });
if (typeof r.completeFileUpload?.id === 'string') return r.completeFileUpload.id;
lastErr = new Error('completeFileUpload returned no id');
} catch (e) { lastErr = e; }
await new Promise((res) => setTimeout(res, 2 ** i * 400));
}
throw lastErr;
} Prevention
- Verify the upstream PUT to the presigned URL succeeded before calling completeFileUpload.
- Pass exactly the fileId returned by the preceding createFileUpload call.
- Inspect `mutationResult.errors` whenever the id field is undefined.
- Retry finalization with backoff — it can be transiently unavailable after a large upload.
When it happens
Trigger: The PUT to the presigned `uploadUrl` failed or was incomplete so the server has no finalized file; the `fileId` passed to `completeFileUpload` does not match the one returned by `createFileUpload`; the server rejected finalization (quota, virus scan, size) and returned a null/error shape.
Common situations: A network blip during the PUT leaving the multipart upload incomplete; passing a stale `fileId` from a previous attempt; a server-side post-upload validation rejecting the file.
Related errors
- createFileUpload mutation did not return an upload target
- createCompany did not return an id
- createPerson did not return an id
- createOpportunity did not return an id
- createOpportunity did not return an id
AI-assisted analysis of twentyhq/twenty@1f5dd2bbd2 (2026-08-12).
Data as JSON: /api/errors/6dae3712b5253022.
Report an issue: GitHub.