Stirling-Tools/Stirling-PDF · error · Error

Missing stored file ID for sharing.

Error message

Missing stored file ID for sharing.

What it means

Thrown in ShareFileModal when storedId is falsy after the upload/refresh logic completes. storedId is read from file.remoteStorageId and optionally updated via uploadHistoryChain(). If neither the existing metadata nor the upload produced a remote ID, the share link API cannot be called because createShareLink(storedId) requires a valid server-side file identifier.

Source

Thrown at frontend/editor/src/core/components/shared/ShareFileModal.tsx:148

        for (const stub of chain) {
          actions.updateStirlingFileStub(stub.id, {
            remoteStorageId: newStoredId,
            remoteStorageUpdatedAt: updatedAt,
            remoteOwnedByCurrentUser: true,
            remoteHasShareLinks: true,
          });
          await fileStorage.updateFileMetadata(stub.id, {
            remoteStorageId: newStoredId,
            remoteStorageUpdatedAt: updatedAt,
            remoteOwnedByCurrentUser: true,
            remoteHasShareLinks: true,
          });
        }
      }

      if (!storedId) {
        throw new Error("Missing stored file ID for sharing.");
      }
      const shareResponse = await createShareLink(storedId);
      setShareToken(shareResponse.token ?? null);

      alert({
        alertType: "success",
        title: t("storageShare.generated", "Share link generated"),
        expandable: false,
        durationMs: 3000,
      });
      if (storedId) {
        actions.updateStirlingFileStub(file.id, { remoteHasShareLinks: true });
        await fileStorage.updateFileMetadata(file.id, {
          remoteHasShareLinks: true,
        });
      }
      if (onUploaded) {
        await onUploaded();

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Verify uploadHistoryChain() return value has a non-null remoteId before proceeding — log and surface the upload error if it doesn't.
  2. Check the server's upload endpoint response shape matches { remoteId, updatedAt } — a version mismatch could return a different field name.
  3. Add explicit error handling around uploadHistoryChain() to catch network failures instead of relying on the downstream storedId check.
  4. If remoteStorageId is already set but stale, force a re-upload rather than silently skipping.

Example fix

// before
const { remoteId: newStoredId, updatedAt, chain } = await uploadHistoryChain(originalFileId, remoteId);
storedId = newStoredId;
// ... later ...
if (!storedId) {
  throw new Error("Missing stored file ID for sharing.");
}

// after
const { remoteId: newStoredId, updatedAt, chain } = await uploadHistoryChain(originalFileId, remoteId);
if (!newStoredId) {
  throw new Error("Upload failed — the server did not return a file ID. Check upload limits and try again.");
}
storedId = newStoredId;
Defensive patterns

Strategy: validation

Validate before calling

// Validate remoteStorageId exists before opening the share modal
const canShare = Boolean(file.remoteStorageId) || Boolean(file.originalFileId);
if (!canShare) {
  showAlert('File must be uploaded before sharing.');
  return;
}
// Also validate uploadHistoryChain result:
if (!newStoredId) {
  throw new Error('Upload did not return a file ID — check server upload limits.');
}

Type guard

function hasRemoteStorageId(file: StirlingFileStub): file is StirlingFileStub & { remoteStorageId: string } {
  return typeof file.remoteStorageId === 'string' && file.remoteStorageId.length > 0;
}

Try / catch

try {
  const result = await uploadHistoryChain(originalFileId, remoteId);
  if (!result.remoteId) {
    setErrorMessage('Upload failed. Please check your connection and try again.');
    return;
  }
  // proceed with share
} catch (error) {
  setErrorMessage(`Failed to prepare file for sharing: ${error instanceof Error ? error.message : 'unknown error'}`);
}

Prevention

When it happens

Trigger: The file was never uploaded to remote storage (remoteStorageId is null) AND the uploadHistoryChain() call returned an empty remoteId. This happens when the upload endpoint fails silently, returns an unexpected shape, or the file is too large and the upload was rejected without throwing.

Common situations: File exceeds server upload size limit but the error was swallowed. Remote storage service is down and uploadHistoryChain returned without setting remoteId. IndexedDB metadata is stale and isUpToDate check incorrectly skipped the upload branch.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/3b57711ab59660ae. Report an issue: GitHub.