{"record":{"id":"f76e0cd712aa84de","repo":"transloadit/uppy","slug":"s3mini-filetype-must-be-a-string","errorCode":null,"errorMessage":"[s3mini] fileType must be a string","messagePattern":"\\[s3mini\\] fileType must be a string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"critical","filePath":"packages/@uppy/aws-s3/src/s3-client/CompanionS3.ts","lineNumber":96,"sourceCode":"      onProgress,\n      signal,\n    })\n\n    return {\n      location: `${url}${fields.key}`, // `url` is returned by the signer as the bucket URL without any path, but trailing slash, so we need to add the key (path) to get the full object URL\n      etag: U.sanitizeETag(xhr.getResponseHeader('etag')),\n      key: fields.key,\n    }\n  }\n\n  public override async createMultipartUpload({\n    key: keyIn,\n    fileType = C.DEFAULT_STREAM_CONTENT_TYPE,\n    metadata,\n    signal,\n  }: IT.CreateMultipartUploadParams) {\n    if (typeof fileType !== 'string') {\n      throw new TypeError(`${C.ERROR_PREFIX}fileType must be a string`)\n    }\n\n    const method = 'POST'\n    const response = await this._fetch('/multipart', {\n      method,\n      body: JSON.stringify({ filename: keyIn, metadata, type: fileType }),\n      headers: { 'content-type': 'application/json' },\n      signal,\n    })\n    const {\n      key,\n      uploadId,\n    }: { key?: string; uploadId?: string; bucket?: string } =\n      await response.json()\n\n    if (uploadId == null) throw new Error('No uploadId returned')\n    if (key == null) throw new Error('No key returned')\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/aws-s3/src/s3-client/CompanionS3.ts#L78-L114","documentation":"The oauth-redirect endpoint needs req.companion.buildURL (from server URL configuration) to construct the redirect back to the provider callback. If buildURL is missing it cannot build any URL and returns 500 — a server configuration problem, not a client error.","triggerScenarios":"Companion is started without the required server host/companionUrl options (or path), so the middleware never attached buildURL; then any request to the oauth-redirect endpoint fails.","commonSituations":"Self-hosting with incomplete server options, especially behind reverse proxies; upgrading Companion where required URL options changed; environment variables for host/URL missing in the deployment.","solutions":["Configure server.host (or companionUrl) and server.path in Companion options","Set the corresponding environment variables (COMPANION_DOMAIN / COMPANION_PATH) in your deployment","Verify startup logs for URL configuration warnings and test the endpoint again"],"exampleFix":"// before\ncompanion({ server: { protocol: 'https' } })\n// after\ncompanion({ server: { host: 'companion.example.com', protocol: 'https', path: '/companion' } })","handlingStrategy":"validation","validationCode":"if (!companionServerConfig.host) throw new Error('server.host is required for OAuth')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate server URL options at startup and fail fast","Use infrastructure-as-code checks for required env vars","Exercise the oauth-redirect path in deployment smoke tests"],"tags":["companion","oauth","configuration","http-500"],"backgroundTag":"missing-server-config","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}