{"record":{"id":"ecd1ac89a80312e1","repo":"transloadit/uppy","slug":"s3mini-endpoint-must-be-a-non-empty-string","errorCode":null,"errorMessage":"[s3mini] endpoint must be a non-empty string","messagePattern":"\\[s3mini\\] endpoint must be a non-empty string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"critical","filePath":"packages/@uppy/aws-s3/src/s3-client/S3mini.ts","lineNumber":72,"sourceCode":"  }: IT.S3Config) {\n    super({ requestAbortTimeout })\n    if ('signRequest' in rest) {\n      const { signRequest } = rest\n      if (!signRequest) {\n        throw new TypeError(\n          'Either signRequest or getCredentials must be provided',\n        )\n      }\n\n      if (signRequest && typeof signRequest !== 'function') {\n        throw new TypeError('signRequest must be a function')\n      }\n\n      this.signRequest = signRequest\n    } else if ('getCredentials' in rest) {\n      const { getCredentials, endpoint } = rest\n      if (typeof endpoint !== 'string' || endpoint.trim().length === 0) {\n        throw new TypeError(C.ERROR_ENDPOINT_REQUIRED)\n      }\n      if (getCredentials && typeof getCredentials !== 'function') {\n        throw new TypeError('getCredentials must be a function')\n      }\n      this.endpoint = new URL(this._ensureValidUrl(endpoint))\n\n      this.getCredentials = getCredentials\n      this.signRequest = this._createCredentialBasedSigner()\n    } else {\n      throw new TypeError(\n        'Either signRequest or getCredentials must be provided',\n      )\n    }\n\n    this.region = region\n    this.requestSizeInBytes = requestSizeInBytes\n  }\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/aws-s3/src/s3-client/S3mini.ts#L54-L90","documentation":"When configuring S3mini with getCredentials (client-side SigV4 signing), a non-empty endpoint string is mandatory because the client must know the bucket URL to presign requests against. The constructor throws ERROR_ENDPOINT_REQUIRED if endpoint is missing, empty, or whitespace-only.","triggerScenarios":"new S3mini({ getCredentials }) with no endpoint, or endpoint: ''/'   ', or endpoint: undefined from a failed env read.","commonSituations":"Endpoint stored in an env var that isn't set locally; endpoint only configured in the signRequest flow and forgotten when switching to getCredentials; trailing/empty values from a config service.","solutions":["Pass a full bucket endpoint like 'https://s3.us-east-1.amazonaws.com/my-bucket' or your S3-compatible host (e.g. MinIO, R2)","Validate/trim the endpoint at app startup and fail fast with a clear message","If you can't expose an endpoint, switch to the signRequest strategy, which needs no endpoint"],"exampleFix":"// before\nnew S3mini({ getCredentials }) // throws: endpoint must be a non-empty string\n\n// after\nnew S3mini({\n  endpoint: 'https://s3.us-east-1.amazonaws.com/my-bucket',\n  getCredentials: async () => (await fetch('/api/s3/credentials')).json(),\n})","handlingStrategy":"validation","validationCode":"if (typeof endpoint !== 'string' || endpoint.trim().length === 0) {\n  throw new Error('Missing S3 endpoint; set S3_ENDPOINT or equivalent')\n}","typeGuard":"const isValidEndpoint = (e: unknown): e is string => typeof e === 'string' && e.trim().length > 0","tryCatchPattern":null,"preventionTips":["Fail fast at startup on missing endpoint env vars","Include endpoint in the same config branch as getCredentials","Consider the signRequest strategy when no endpoint is available"],"tags":["aws-s3","configuration","missing-endpoint","env-var"],"backgroundTag":"missing-required-config","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}