{"record":{"id":"5d67b02e3e517016","repo":"transloadit/uppy","slug":"s3mini-uploadid-must-be-a-non-empty-string","errorCode":null,"errorMessage":"[s3mini] uploadId must be a non-empty string","messagePattern":"\\[s3mini\\] uploadId must be a non-empty string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"critical","filePath":"packages/@uppy/aws-s3/src/s3-client/CompanionS3.ts","lineNumber":160,"sourceCode":"    })\n\n    const etag = U.sanitizeETag(xhr.getResponseHeader('etag'))\n    if (etag == null) {\n      throw new Error(\n        `${C.ERROR_PREFIX}Missing ETag in uploadPart response headers`,\n      )\n    }\n\n    return { etag }\n  }\n\n  public override async listParts({\n    uploadId,\n    key,\n    signal,\n  }: IT.ListPartsParams): Promise<IT.UploadPart[]> {\n    if (!uploadId) {\n      throw new TypeError(C.ERROR_UPLOAD_ID_REQUIRED)\n    }\n\n    const response = await this._fetch(\n      `/multipart/${encodeURIComponent(uploadId)}?${new URLSearchParams({ key })}`,\n      {\n        method: 'GET',\n        signal,\n      },\n    )\n\n    const parts: { PartNumber: string; ETag: string }[] = await response.json()\n\n    return parts.map((p) => ({\n      partNumber: parseInt(String(p.PartNumber), 10),\n      etag: String(p.ETag),\n    }))\n  }\n","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/aws-s3/src/s3-client/CompanionS3.ts#L142-L178","documentation":"Preauth requires a preAuthSecret option on the Companion server, used by tokenService.generateEncryptedToken to encrypt the pre-auth token. If preAuthSecret is null/undefined, Companion returns 500 because it cannot securely mint the token.","triggerScenarios":"Running Companion with a provider credentialsURL configured but no preAuthSecret option (or env var) set, then hitting the preauth endpoint.","commonSituations":"Missing COMPANION_PREAUTH_SECRET environment variable in deployment; secret removed during config refactor; new deployment template that omits the secret.","solutions":["Set the preAuthSecret Companion option or the COMPANION_PREAUTH_SECRET environment variable to a strong random secret","Restart Companion after adding the secret","Verify the secret is present in the environment of the actual running process (not just the shell)"],"exampleFix":"// before\ncompanion({ providerOptions: { url: { credentialsURL: '...' } } })\n// after\ncompanion({\n  preAuthSecret: process.env.COMPANION_PREAUTH_SECRET,\n  providerOptions: { url: { credentialsURL: '...' } },\n})","handlingStrategy":"validation","validationCode":"if (!process.env.COMPANION_PREAUTH_SECRET) {\n  throw new Error('COMPANION_PREAUTH_SECRET must be set to use preauth')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add startup assertions for all required secrets","Generate secrets with a strong random source and store them in a secret manager","Never deploy preauth-enabled providers without the secret in every environment"],"tags":["companion","preauth","secrets","http-500"],"backgroundTag":"missing-env-var","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}