transloadit/uppy · warning

Invalid URL

Error message

Invalid URL

What it means

Companion's Google Picker endpoint rejects the request when the picker result's url field fails validation. Before streaming a 'photos' platform file, Companion validates the URL (including blocking local/internal URLs unless allowLocalUrls is enabled). This is a 400 client error.

Source

Thrown at packages/@uppy/companion/src/server/controllers/googlePicker.ts:45

const get = async (req: Request, res: Response): Promise<void> => {
  try {
    logger.debug('Google Picker file import handler running', undefined, req.id)

    const allowLocalUrls = false

    const parsedBody = googlePickerBodySchema.safeParse(req.body)
    if (!parsedBody.success) {
      res.status(400).json({ error: 'Invalid request body' })
      return
    }
    const { accessToken, platform } = parsedBody.data

    if (
      platform === 'photos' &&
      !validateURL(parsedBody.data.url, allowLocalUrls)
    ) {
      res.status(400).json({ error: 'Invalid URL' })
      return
    }

    const download = () => {
      if (platform === 'drive') {
        return streamGoogleFile({
          token: accessToken,
          id: parsedBody.data.fileId,
        })
      }
      return downloadURL(parsedBody.data.url, allowLocalUrls, req.id, {
        headers: getAuthHeader(accessToken),
      })
    }

    await startDownUpload({ req, res, download, getSize: undefined })
  } catch (err) {
    logger.error(err, 'controller.googlePicker.error', req.id)

View on GitHub (pinned to 5d4dedd02a)

Solutions

  1. Verify the client forwards the exact url field from the Google Picker response
  2. If testing with local URLs, enable allowLocalUrls in Companion config (dev only)
  3. Ensure url is an absolute http(s) URL

Example fix

// before
data: { accessToken, platform: 'photos', url: '/some/path' }
// after
data: { accessToken, platform: 'photos', url: 'https://lh3.googleusercontent.com/...' }
Defensive patterns

Strategy: validation

Validate before calling

function isValidPickerUrl(url, allowLocal = false) {
  try {
    const u = new URL(url)
    if (!['http:', 'https:'].includes(u.protocol)) return false
    if (!allowLocal && /^(localhost|127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/.test(u.hostname)) return false
    return true
  } catch { return false }
}

Type guard

const isNonEmptyString = (v) => typeof v === 'string' && v.length > 0

Prevention

When it happens

Trigger: POST /google-picker/get with platform === 'photos' and a missing, malformed, or non-URL value in data.url; also when url points to localhost/private ranges and allowLocalUrls is false.

Common situations: Client sends a Picker response payload that was constructed manually or truncated; forwarding a relative URL; testing against a local URL while allowLocalUrls is not set in Companion options.

Related errors


AI-assisted analysis of transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/f2984774a0a22fb1. Report an issue: GitHub.