overleaf/overleaf · warning · FileCannotRefreshError

This file cannot be refreshed

Error message

This file cannot be refreshed

What it means

handleError recognizes an instance of FileCannotRefreshError and returns 400 'This file cannot be refreshed'. The domain layer raises this when a linked file's refresh operation is not permitted in its current state (e.g. the file is no longer linked, was deleted remotely, or lacks a refreshable source). It is a deliberate business-rule rejection, not an unexpected fault.

Source

Thrown at services/web/app/src/Features/LinkedFiles/LinkedFilesController.mjs:258

      )
    } else if (error instanceof NotOriginalImporterError) {
      res.status(400)
      plainTextResponse(
        res,
        'You are not the user who originally imported this file'
      )
    } else if (error instanceof FeatureNotAvailableError) {
      res.status(400)
      plainTextResponse(res, 'This feature is not enabled on your account')
    } else if (error instanceof RemoteServiceError) {
      if (error.info?.statusCode === 403) {
        res.status(400).json({ relink: true })
      } else {
        res.status(502)
        plainTextResponse(res, 'The remote service produced an error')
      }
    } else if (error instanceof FileCannotRefreshError) {
      res.status(400)
      plainTextResponse(res, 'This file cannot be refreshed')
    } else if (error.message === 'project_has_too_many_files') {
      res.status(400)
      plainTextResponse(res, 'too many files')
    } else if (/\bECONNREFUSED\b/.test(error.message)) {
      res.status(500)
      plainTextResponse(res, 'Importing references is not currently available')
    } else if (error instanceof FileTooLargeError) {
      res.status(422)
      plainTextResponse(res, 'File too large')
    } else {
      next(error)
    }
  },
}

View on GitHub (pinned to 28ad3b03b7)

Solutions

  1. Check the linked file's status/provider before attempting refresh
  2. Ask the user to relink or re-import the file if the link is stale
  3. Remove or archive the broken linked file
  4. Verify the provider still exposes the underlying file

Example fix

// before
fetch(`/linkedservice/refresh/${fileId}`)
// after: pre-check link status client-side
const { status } = await fetch(`/linkedservice/status/${fileId}`).then(r => r.json())
if (status !== 'linked') showRelinkPrompt()
else fetch(`/linkedservice/refresh/${fileId}`)
Defensive patterns

Strategy: validation

Validate before calling

const link = await getLinkedFileStatus(fileId)
if (!link || link.status !== 'linked') {
  throw new Error('file is not refreshable; relink first')
}

Type guard

function canRefresh(link) {
  return link != null && link.status === 'linked' && typeof link.providerId === 'string'
}

Try / catch

try {
  await refreshLinkedFile(fileId)
} catch (e) {
  if (e instanceof FileCannotRefreshError) return showRelinkUI()
  throw e
}

Prevention

When it happens

Trigger: A POST/refresh request on a linked file whose provider state makes refresh impossible, causing the service layer to reject with FileCannotRefreshError which handleError converts to a 400 plain-text response.

Common situations: User tries to refresh a file whose remote counterpart was deleted or access revoked, file created by a deprecated provider, stale link after provider-side policy change.

Related errors


AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03). Data as JSON: /api/errors/1d865882bc66ad76. Report an issue: GitHub.